From 19afe671570c300ac176a510b40ea11d0081e403 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Wed, 26 Nov 2014 15:27:39 +0000 Subject: [PATCH] Reverting r222828 and r222810-r222812 as they broke the build on Windows. http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/11753 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222833 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/ExecutionEngine/JITEventListener.h | 19 +- include/llvm/ExecutionEngine/ObjectBuffer.h | 76 +++++ include/llvm/ExecutionEngine/ObjectImage.h | 76 +++++ .../ExecutionEngine/RTDyldMemoryManager.h | 7 +- include/llvm/ExecutionEngine/RuntimeDyld.h | 43 +-- lib/ExecutionEngine/CMakeLists.txt | 1 + lib/ExecutionEngine/ExecutionEngine.cpp | 11 +- .../IntelJITEvents/IntelJITEventListener.cpp | 40 +-- lib/ExecutionEngine/JITEventListener.cpp | 15 + lib/ExecutionEngine/MCJIT/MCJIT.cpp | 71 +++-- lib/ExecutionEngine/MCJIT/MCJIT.h | 13 +- lib/ExecutionEngine/MCJIT/ObjectBuffer.h | 48 ---- .../OProfileJIT/OProfileJITEventListener.cpp | 97 +++---- .../RuntimeDyld/CMakeLists.txt | 2 +- ...istrationListener.cpp => GDBRegistrar.cpp} | 78 ++---- .../RuntimeDyld/JITRegistrar.h | 44 +++ .../RuntimeDyld/ObjectImageCommon.h | 86 ++++++ .../RuntimeDyld/RuntimeDyld.cpp | 154 +++++++---- .../RuntimeDyld/RuntimeDyldELF.cpp | 260 ++++++++++-------- .../RuntimeDyld/RuntimeDyldELF.h | 27 +- .../RuntimeDyld/RuntimeDyldImpl.h | 29 +- .../RuntimeDyld/RuntimeDyldMachO.cpp | 60 ++-- .../RuntimeDyld/RuntimeDyldMachO.h | 32 ++- .../Targets/RuntimeDyldMachOAArch64.h | 13 +- .../RuntimeDyld/Targets/RuntimeDyldMachOARM.h | 54 ++-- .../Targets/RuntimeDyldMachOI386.h | 76 ++--- .../Targets/RuntimeDyldMachOX86_64.h | 13 +- tools/lli/RemoteMemoryManager.cpp | 3 +- tools/lli/RemoteMemoryManager.h | 3 +- tools/llvm-jitlistener/llvm-jitlistener.cpp | 2 +- tools/llvm-rtdyld/llvm-rtdyld.cpp | 56 ++-- 31 files changed, 871 insertions(+), 638 deletions(-) create mode 100644 include/llvm/ExecutionEngine/ObjectBuffer.h create mode 100644 include/llvm/ExecutionEngine/ObjectImage.h create mode 100644 lib/ExecutionEngine/JITEventListener.cpp delete mode 100644 lib/ExecutionEngine/MCJIT/ObjectBuffer.h rename lib/ExecutionEngine/RuntimeDyld/{GDBRegistrationListener.cpp => GDBRegistrar.cpp} (69%) create mode 100644 lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h create mode 100644 lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h index c3edec86878..cef3aa27d5c 100644 --- a/include/llvm/ExecutionEngine/JITEventListener.h +++ b/include/llvm/ExecutionEngine/JITEventListener.h @@ -15,7 +15,6 @@ #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" @@ -26,10 +25,7 @@ class Function; class MachineFunction; class OProfileWrapper; class IntelJITEventsWrapper; - -namespace object { - class ObjectFile; -} +class ObjectImage; /// JITEvent_EmittedFunctionDetails - Helper struct for containing information /// about a generated machine code function. @@ -61,7 +57,7 @@ public: public: JITEventListener() {} - virtual ~JITEventListener() {} + virtual ~JITEventListener(); /// NotifyObjectEmitted - Called after an object has been successfully /// emitted to memory. NotifyFunctionEmitted will not be called for @@ -71,15 +67,11 @@ 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 object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &L) {} + virtual void NotifyObjectEmitted(const ObjectImage &Obj) {} /// NotifyFreeingObject - Called just before the memory associated with /// a previously emitted object is released. - virtual void NotifyFreeingObject(const object::ObjectFile &Obj) {} - - // Get a pointe to the GDB debugger registration listener. - static JITEventListener *createGDBRegistrationListener(); + virtual void NotifyFreeingObject(const ObjectImage &Obj) {} #if LLVM_USE_INTEL_JITEVENTS // Construct an IntelJITEventListener @@ -113,8 +105,7 @@ public: return nullptr; } #endif // USE_OPROFILE -private: - virtual void anchor(); + }; } // end namespace llvm. diff --git a/include/llvm/ExecutionEngine/ObjectBuffer.h b/include/llvm/ExecutionEngine/ObjectBuffer.h new file mode 100644 index 00000000000..ee4820aa6ee --- /dev/null +++ b/include/llvm/ExecutionEngine/ObjectBuffer.h @@ -0,0 +1,76 @@ +//===---- 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 { + +/// 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. +class ObjectBuffer { + virtual void anchor(); +public: + ObjectBuffer() {} + ObjectBuffer(std::unique_ptr Buf) : Buffer(std::move(Buf)) {} + virtual ~ObjectBuffer() {} + + MemoryBufferRef getMemBuffer() const { return Buffer->getMemBufferRef(); } + + const char *getBufferStart() const { return Buffer->getBufferStart(); } + size_t getBufferSize() const { return Buffer->getBufferSize(); } + StringRef getBuffer() const { return Buffer->getBuffer(); } + StringRef getBufferIdentifier() const { + return Buffer->getBufferIdentifier(); + } + +protected: + // The memory contained in an ObjectBuffer + std::unique_ptr Buffer; +}; + +/// 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 = + MemoryBuffer::getMemBuffer(StringRef(SV.data(), SV.size()), "", false); + } + +protected: + SmallVector 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 00000000000..dc142bd70af --- /dev/null +++ b/include/llvm/ExecutionEngine/ObjectImage.h @@ -0,0 +1,76 @@ +//===---- 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 Buffer; + +public: + ObjectImage(std::unique_ptr Input) : Buffer(std::move(Input)) {} + virtual ~ObjectImage() {} + + virtual object::symbol_iterator begin_symbols() const = 0; + virtual object::symbol_iterator end_symbols() const = 0; + iterator_range symbols() const { + return iterator_range(begin_symbols(), + end_symbols()); + } + + virtual object::section_iterator begin_sections() const = 0; + virtual object::section_iterator end_sections() const = 0; + iterator_range sections() const { + return iterator_range(begin_sections(), + end_sections()); + } + + virtual /* Triple::ArchType */ unsigned getArch() const = 0; + + // Return the name associated with this ObjectImage. + // This is usually the name of the file or MemoryBuffer that the the + // ObjectBuffer was constructed from. + StringRef getImageName() const { return Buffer->getBufferIdentifier(); } + + // 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 ef81cd328bd..b941efcad01 100644 --- a/include/llvm/ExecutionEngine/RTDyldMemoryManager.h +++ b/include/llvm/ExecutionEngine/RTDyldMemoryManager.h @@ -22,10 +22,7 @@ namespace llvm { class ExecutionEngine; - - namespace object { - class ObjectFile; - } +class ObjectImage; // RuntimeDyld clients often want to handle the memory management of // what gets placed where. For JIT clients, this is the subset of @@ -112,7 +109,7 @@ public: /// address space can use this call to remap the section addresses for the /// newly loaded object. virtual void notifyObjectLoaded(ExecutionEngine *EE, - const object::ObjectFile &) {} + const ObjectImage *) {} /// This method is called when object loading is complete and section page /// permissions can be applied. It is up to the memory manager implementation diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index 799fc34eb65..3605b9e44d7 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -15,19 +15,19 @@ #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 namespace llvm { namespace object { class ObjectFile; - template class OwningBinary; } class RuntimeDyldImpl; class RuntimeDyldCheckerImpl; +class ObjectImage; class RuntimeDyld { friend class RuntimeDyldCheckerImpl; @@ -46,35 +46,22 @@ protected: // 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 - 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(); - /// Add the referenced object file to the list of objects to be loaded and - /// relocated. - std::unique_ptr loadObject(const object::ObjectFile &O); + /// 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. + std::unique_ptr + loadObject(std::unique_ptr 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. + std::unique_ptr + loadObject(std::unique_ptr InputObject); /// 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 diff --git a/lib/ExecutionEngine/CMakeLists.txt b/lib/ExecutionEngine/CMakeLists.txt index 208495c8847..fae5bb900b9 100644 --- a/lib/ExecutionEngine/CMakeLists.txt +++ b/lib/ExecutionEngine/CMakeLists.txt @@ -3,6 +3,7 @@ add_llvm_library(LLVMExecutionEngine ExecutionEngine.cpp ExecutionEngineBindings.cpp + JITEventListener.cpp RTDyldMemoryManager.cpp TargetSelect.cpp ) diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 4d4cb2a26d8..5a6d65624be 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -16,7 +16,8 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Statistic.h" #include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/ExecutionEngine/JITEventListener.h" +#include "llvm/ExecutionEngine/ObjectBuffer.h" +#include "llvm/ExecutionEngine/ObjectCache.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" @@ -42,15 +43,17 @@ using namespace llvm; STATISTIC(NumInitBytes, "Number of bytes of global vars initialized"); STATISTIC(NumGlobals , "Number of global vars initialized"); +// Pin the vtable to this file. +void ObjectCache::anchor() {} +void ObjectBuffer::anchor() {} +void ObjectBufferStream::anchor() {} + ExecutionEngine *(*ExecutionEngine::MCJITCtor)( std::unique_ptr M, std::string *ErrorStr, RTDyldMemoryManager *MCJMM, std::unique_ptr TM) = nullptr; ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr M, std::string *ErrorStr) =nullptr; -// Anchor for the JITEventListener class. -void JITEventListener::anchor() {} - ExecutionEngine::ExecutionEngine(std::unique_ptr M) : EEState(*this), LazyFunctionCreator(nullptr) { diff --git a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp index c35e5244ecd..b23ca88baf1 100644 --- a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp +++ b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp @@ -21,6 +21,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/DebugInfo/DIContext.h" +#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -31,7 +32,6 @@ using namespace llvm; using namespace llvm::jitprofiling; -using namespace llvm::object; #define DEBUG_TYPE "amplifier-jit-event-listener" @@ -48,7 +48,6 @@ class IntelJITEventListener : public JITEventListener { typedef DenseMap ObjectMap; ObjectMap LoadedObjectMap; - std::map> DebugObjects; public: IntelJITEventListener(IntelJITEventsWrapper* libraryWrapper) { @@ -58,10 +57,9 @@ public: ~IntelJITEventListener() { } - void NotifyObjectEmitted(const ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &L) override; + virtual void NotifyObjectEmitted(const ObjectImage &Obj); - void NotifyFreeingObject(const ObjectFile &Obj) override; + virtual void NotifyFreeingObject(const ObjectImage &Obj); }; static LineNumberInfo DILineInfoToIntelJITFormat(uintptr_t StartAddress, @@ -97,29 +95,23 @@ static iJIT_Method_Load FunctionDescToIntelJITFormat( return Result; } -void IntelJITEventListener::NotifyObjectEmitted( - const ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &L) { - - OwningBinary DebugObjOwner = L.getObjectForDebug(Obj); - const ObjectFile &DebugObj = *DebugObjOwner.getBinary(); - +void IntelJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) { // Get the address of the object image for use as a unique identifier - const void* ObjData = DebugObj.getData().data(); - DIContext* Context = DIContext::getDWARFContext(DebugObj); + const void* ObjData = Obj.getData().data(); + DIContext* Context = DIContext::getDWARFContext(*Obj.getObjectFile()); MethodAddressVector Functions; // Use symbol info to iterate functions in the object. - for (symbol_iterator I = DebugObj.symbol_begin(), - E = DebugObj.symbol_end(); + for (object::symbol_iterator I = Obj.begin_symbols(), + E = Obj.end_symbols(); I != E; ++I) { std::vector LineInfo; std::string SourceFileName; - SymbolRef::Type SymType; + object::SymbolRef::Type SymType; if (I->getType(SymType)) continue; - if (SymType == SymbolRef::ST_Function) { + if (SymType == object::SymbolRef::ST_Function) { StringRef Name; uint64_t Addr; uint64_t Size; @@ -170,18 +162,11 @@ void IntelJITEventListener::NotifyObjectEmitted( // registered function addresses for each loaded object. We will // use the MethodIDs map to get the registered ID for each function. LoadedObjectMap[ObjData] = Functions; - DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner); } -void IntelJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) { - // This object may not have been registered with the listener. If it wasn't, - // bail out. - if (DebugObjects.find(Obj.getData().data()) == DebugObjects.end()) - return; - +void IntelJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) { // Get the address of the object image for use as a unique identifier - const ObjectFile &DebugObj = *DebugObjects[Obj.getData().data()].getBinary(); - const void* ObjData = DebugObj.getData().data(); + const void* ObjData = Obj.getData().data(); // Get the object's function list from LoadedObjectMap ObjectMap::iterator OI = LoadedObjectMap.find(ObjData); @@ -205,7 +190,6 @@ void IntelJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) { // Erase the object from LoadedObjectMap LoadedObjectMap.erase(OI); - DebugObjects.erase(Obj.getData().data()); } } // anonymous namespace. diff --git a/lib/ExecutionEngine/JITEventListener.cpp b/lib/ExecutionEngine/JITEventListener.cpp new file mode 100644 index 00000000000..2a6a0070d97 --- /dev/null +++ b/lib/ExecutionEngine/JITEventListener.cpp @@ -0,0 +1,15 @@ +//===-- JITEventListener.cpp ----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/JITEventListener.h" + +using namespace llvm; + +// Out-of-line definition of the virtual destructor as this is the key function. +JITEventListener::~JITEventListener() {} diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 58cf4e5e6dd..da5f03799e3 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -11,6 +11,8 @@ #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/ExecutionEngine/MCJIT.h" +#include "llvm/ExecutionEngine/ObjectBuffer.h" +#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" @@ -19,7 +21,6 @@ #include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/Object/Archive.h" -#include "llvm/Object/ObjectFile.h" #include "llvm/PassManager.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" @@ -30,8 +31,6 @@ using namespace llvm; -void ObjectCache::anchor() {} - namespace { static struct RegisterJIT { @@ -75,7 +74,6 @@ MCJIT::MCJIT(std::unique_ptr M, std::unique_ptr tm, OwnedModules.addModule(std::move(First)); setDataLayout(TM->getSubtargetImpl()->getDataLayout()); - RegisterJITEventListener(JITEventListener::createGDBRegistrationListener()); } MCJIT::~MCJIT() { @@ -101,13 +99,13 @@ bool MCJIT::removeModule(Module *M) { } void MCJIT::addObjectFile(std::unique_ptr Obj) { - std::unique_ptr L = Dyld.loadObject(*Obj); - if (Dyld.hasError()) + std::unique_ptr LoadedObject = Dyld.loadObject(std::move(Obj)); + if (!LoadedObject || Dyld.hasError()) report_fatal_error(Dyld.getErrorString()); - NotifyObjectEmitted(*Obj, *L); + NotifyObjectEmitted(*LoadedObject); - LoadedObjects.push_back(std::move(Obj)); + LoadedObjects.push_back(std::move(LoadedObject)); } void MCJIT::addObjectFile(object::OwningBinary Obj) { @@ -127,7 +125,7 @@ void MCJIT::setObjectCache(ObjectCache* NewCache) { ObjCache = NewCache; } -std::unique_ptr MCJIT::emitObject(Module *M) { +std::unique_ptr MCJIT::emitObject(Module *M) { MutexGuard locked(lock); // This must be a module which has already been added but not loaded to this @@ -140,32 +138,30 @@ std::unique_ptr MCJIT::emitObject(Module *M) { PM.add(new DataLayoutPass()); // The RuntimeDyld will take ownership of this shortly - SmallVector ObjBufferSV; - raw_svector_ostream ObjStream(ObjBufferSV); + std::unique_ptr CompiledObject(new ObjectBufferStream()); // Turn the machine code intermediate representation into bytes in memory // that may be executed. - if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !getVerifyModules())) + if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(), + !getVerifyModules())) { report_fatal_error("Target does not support MC emission!"); + } // Initialize passes. PM.run(*M); // Flush the output buffer to get the generated code into memory - ObjStream.flush(); - - std::unique_ptr CompiledObjBuffer( - new ObjectMemoryBuffer(std::move(ObjBufferSV))); + CompiledObject->flush(); // If we have an object cache, tell it about the new object. // Note that we're using the compiled image, not the loaded image (as below). if (ObjCache) { // MemoryBuffer is a thin wrapper around the actual memory, so it's OK // to create a temporary object here and delete it after the call. - MemoryBufferRef MB = CompiledObjBuffer->getMemBufferRef(); + MemoryBufferRef MB = CompiledObject->getMemBuffer(); ObjCache->notifyObjectCompiled(M, MB); } - return CompiledObjBuffer; + return CompiledObject; } void MCJIT::generateCodeForModule(Module *M) { @@ -180,10 +176,14 @@ void MCJIT::generateCodeForModule(Module *M) { if (OwnedModules.hasModuleBeenLoaded(M)) return; - std::unique_ptr ObjectToLoad; + std::unique_ptr ObjectToLoad; // Try to load the pre-compiled object from cache if possible - if (ObjCache) - ObjectToLoad = ObjCache->getObject(M); + if (ObjCache) { + if (std::unique_ptr PreCompiledObject = + ObjCache->getObject(M)) + ObjectToLoad = + llvm::make_unique(std::move(PreCompiledObject)); + } // If the cache did not contain a suitable object, compile the object if (!ObjectToLoad) { @@ -193,18 +193,17 @@ void MCJIT::generateCodeForModule(Module *M) { // Load the object into the dynamic linker. // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list). - ErrorOr> LoadedObject = - object::ObjectFile::createObjectFile(ObjectToLoad->getMemBufferRef()); - std::unique_ptr L = - Dyld.loadObject(*LoadedObject.get()); - - if (Dyld.hasError()) + std::unique_ptr LoadedObject = + Dyld.loadObject(std::move(ObjectToLoad)); + if (!LoadedObject) report_fatal_error(Dyld.getErrorString()); - NotifyObjectEmitted(*LoadedObject.get(), *L); + // FIXME: Make this optional, maybe even move it to a JIT event listener + LoadedObject->registerWithDebugger(); + + NotifyObjectEmitted(*LoadedObject); - Buffers.push_back(std::move(ObjectToLoad)); - LoadedObjects.push_back(std::move(*LoadedObject)); + LoadedObjects.push_back(std::move(LoadedObject)); OwnedModules.markModuleAsLoaded(M); } @@ -550,7 +549,6 @@ void MCJIT::RegisterJITEventListener(JITEventListener *L) { MutexGuard locked(lock); EventListeners.push_back(L); } - void MCJIT::UnregisterJITEventListener(JITEventListener *L) { if (!L) return; @@ -561,17 +559,14 @@ void MCJIT::UnregisterJITEventListener(JITEventListener *L) { EventListeners.pop_back(); } } - -void MCJIT::NotifyObjectEmitted(const object::ObjectFile& Obj, - const RuntimeDyld::LoadedObjectInfo &L) { +void MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) { MutexGuard locked(lock); - MemMgr.notifyObjectLoaded(this, Obj); + MemMgr.notifyObjectLoaded(this, &Obj); for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { - EventListeners[I]->NotifyObjectEmitted(Obj, L); + EventListeners[I]->NotifyObjectEmitted(Obj); } } - -void MCJIT::NotifyFreeingObject(const object::ObjectFile& Obj) { +void MCJIT::NotifyFreeingObject(const ObjectImage& Obj) { MutexGuard locked(lock); for (JITEventListener *L : EventListeners) L->NotifyFreeingObject(Obj); diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h index 6f92e51b64c..bc943b9b886 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -10,12 +10,12 @@ #ifndef LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H #define LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H -#include "ObjectBuffer.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/ObjectCache.h" +#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/IR/Module.h" @@ -57,7 +57,7 @@ public: } void notifyObjectLoaded(ExecutionEngine *EE, - const object::ObjectFile &Obj) override { + const ObjectImage *Obj) override { ClientMM->notifyObjectLoaded(EE, Obj); } @@ -222,7 +222,7 @@ class MCJIT : public ExecutionEngine { SmallVector, 2> Archives; SmallVector, 2> Buffers; - SmallVector, 2> LoadedObjects; + SmallVector, 2> LoadedObjects; // An optional ObjectCache to be notified of compiled objects and used to // perform lookup of pre-compiled code to avoid re-compilation. @@ -341,11 +341,10 @@ protected: /// this function call is expected to be the contained module. The module /// is passed as a parameter here to prepare for multiple module support in /// the future. - std::unique_ptr emitObject(Module *M); + std::unique_ptr emitObject(Module *M); - void NotifyObjectEmitted(const object::ObjectFile& Obj, - const RuntimeDyld::LoadedObjectInfo &L); - void NotifyFreeingObject(const object::ObjectFile& Obj); + void NotifyObjectEmitted(const ObjectImage& Obj); + void NotifyFreeingObject(const ObjectImage& Obj); uint64_t getExistingSymbolAddress(const std::string &Name); Module *findModuleForSymbol(const std::string &Name, diff --git a/lib/ExecutionEngine/MCJIT/ObjectBuffer.h b/lib/ExecutionEngine/MCJIT/ObjectBuffer.h deleted file mode 100644 index 92310f3eb54..00000000000 --- a/lib/ExecutionEngine/MCJIT/ObjectBuffer.h +++ /dev/null @@ -1,48 +0,0 @@ -//===--- ObjectBuffer.h - Utility class to wrap object memory ---*- C++ -*-===// -// -// 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 { - -class ObjectMemoryBuffer : public MemoryBuffer { -public: - template - ObjectMemoryBuffer(SmallVector SV) - : SV(SV), BufferName("") { - init(this->SV.begin(), this->SV.end(), false); - } - - template - ObjectMemoryBuffer(SmallVector SV, StringRef Name) - : SV(SV), BufferName(Name) { - init(this->SV.begin(), this->SV.end(), false); - } - const char* getBufferIdentifier() const override { return BufferName.c_str(); } - - BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; } - -private: - SmallVector SV; - std::string BufferName; -}; - -} // namespace llvm - -#endif diff --git a/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp b/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp index 92a67b9b2a6..5a8ccb66e52 100644 --- a/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp +++ b/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp @@ -18,8 +18,8 @@ #include "llvm/IR/DebugInfo.h" #include "llvm/IR/Function.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/ExecutionEngine/OProfileWrapper.h" -#include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -31,34 +31,31 @@ using namespace llvm; using namespace llvm::jitprofiling; -using namespace llvm::object; #define DEBUG_TYPE "oprofile-jit-event-listener" namespace { class OProfileJITEventListener : public JITEventListener { - std::unique_ptr Wrapper; + OProfileWrapper& Wrapper; void initialize(); - std::map> DebugObjects; public: - OProfileJITEventListener(std::unique_ptr LibraryWrapper) - : Wrapper(std::move(LibraryWrapper)) { + OProfileJITEventListener(OProfileWrapper& LibraryWrapper) + : Wrapper(LibraryWrapper) { initialize(); } ~OProfileJITEventListener(); - void NotifyObjectEmitted(const ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &L) override; + virtual void NotifyObjectEmitted(const ObjectImage &Obj); - void NotifyFreeingObject(const ObjectFile &Obj) override; + virtual void NotifyFreeingObject(const ObjectImage &Obj); }; void OProfileJITEventListener::initialize() { - if (!Wrapper->op_open_agent()) { + if (!Wrapper.op_open_agent()) { const std::string err_str = sys::StrError(); DEBUG(dbgs() << "Failed to connect to OProfile agent: " << err_str << "\n"); } else { @@ -67,8 +64,8 @@ void OProfileJITEventListener::initialize() { } OProfileJITEventListener::~OProfileJITEventListener() { - if (Wrapper->isAgentAvailable()) { - if (Wrapper->op_close_agent() == -1) { + if (Wrapper.isAgentAvailable()) { + if (Wrapper.op_close_agent() == -1) { const std::string err_str = sys::StrError(); DEBUG(dbgs() << "Failed to disconnect from OProfile agent: " << err_str << "\n"); @@ -78,22 +75,17 @@ OProfileJITEventListener::~OProfileJITEventListener() { } } -void OProfileJITEventListener::NotifyObjectEmitted( - const ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &L) { - if (!Wrapper->isAgentAvailable()) { +void OProfileJITEventListener::NotifyObjectEmitted(const ObjectImage &Obj) { + if (!Wrapper.isAgentAvailable()) { return; } - OwningBinary DebugObjOwner = L.getObjectForDebug(Obj); - const ObjectFile &DebugObj = *DebugObjOwner.getBinary(); - // Use symbol info to iterate functions in the object. - for (symbol_iterator I = DebugObj.symbol_begin(), E = DebugObj.symbol_end(); + for (object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E; ++I) { - SymbolRef::Type SymType; + object::SymbolRef::Type SymType; if (I->getType(SymType)) continue; - if (SymType == SymbolRef::ST_Function) { + if (SymType == object::SymbolRef::ST_Function) { StringRef Name; uint64_t Addr; uint64_t Size; @@ -101,7 +93,7 @@ void OProfileJITEventListener::NotifyObjectEmitted( if (I->getAddress(Addr)) continue; if (I->getSize(Size)) continue; - if (Wrapper->op_write_native_code(Name.data(), Addr, (void*)Addr, Size) + if (Wrapper.op_write_native_code(Name.data(), Addr, (void*)Addr, Size) == -1) { DEBUG(dbgs() << "Failed to tell OProfile about native function " << Name << " at [" @@ -111,48 +103,45 @@ void OProfileJITEventListener::NotifyObjectEmitted( // TODO: support line number info (similar to IntelJITEventListener.cpp) } } - - DebugObjects[Obj.getData().data()] = std::move(DebugObjOwner); } -void OProfileJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) { - if (Wrapper->isAgentAvailable()) { - - // If there was no agent registered when the original object was loaded then - // we won't have created a debug object for it, so bail out. - if (DebugObjects.find(Obj.getData().data()) == DebugObjects.end()) - return; - - const ObjectFile &DebugObj = *DebugObjects[Obj.getData().data()].getBinary(); - - // Use symbol info to iterate functions in the object. - for (symbol_iterator I = DebugObj.symbol_begin(), - E = DebugObj.symbol_end(); - I != E; ++I) { - SymbolRef::Type SymType; - if (I->getType(SymType)) continue; - if (SymType == SymbolRef::ST_Function) { - uint64_t Addr; - if (I->getAddress(Addr)) continue; - - if (Wrapper->op_unload_native_code(Addr) == -1) { - DEBUG(dbgs() - << "Failed to tell OProfile about unload of native function at " - << (void*)Addr << "\n"); - continue; - } +void OProfileJITEventListener::NotifyFreeingObject(const ObjectImage &Obj) { + if (!Wrapper.isAgentAvailable()) { + return; + } + + // Use symbol info to iterate functions in the object. + for (object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); + I != E; ++I) { + object::SymbolRef::Type SymType; + if (I->getType(SymType)) continue; + if (SymType == object::SymbolRef::ST_Function) { + uint64_t Addr; + if (I->getAddress(Addr)) continue; + + if (Wrapper.op_unload_native_code(Addr) == -1) { + DEBUG(dbgs() + << "Failed to tell OProfile about unload of native function at " + << (void*)Addr << "\n"); + continue; } } } - - DebugObjects.erase(Obj.getData().data()); } } // anonymous namespace. namespace llvm { JITEventListener *JITEventListener::createOProfileJITEventListener() { - return new OProfileJITEventListener(llvm::make_unique()); + static std::unique_ptr JITProfilingWrapper( + new OProfileWrapper); + return new OProfileJITEventListener(*JITProfilingWrapper); +} + +// for testing +JITEventListener *JITEventListener::createOProfileJITEventListener( + OProfileWrapper* TestImpl) { + return new OProfileJITEventListener(*TestImpl); } } // namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt b/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt index 583d7a0aa41..eb1a60b60d0 100644 --- a/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt +++ b/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt @@ -1,5 +1,5 @@ add_llvm_library(LLVMRuntimeDyld - GDBRegistrationListener.cpp + GDBRegistrar.cpp RuntimeDyld.cpp RuntimeDyldChecker.cpp RuntimeDyldELF.cpp diff --git a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp similarity index 69% rename from lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp rename to lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp index 13d5672a82b..dfa3a203ac3 100644 --- a/lib/ExecutionEngine/RuntimeDyld/GDBRegistrationListener.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/GDBRegistrar.cpp @@ -1,4 +1,4 @@ -//===----- GDBRegistrationListener.cpp - Registers objects with GDB -------===// +//===-- GDBRegistrar.cpp - Registers objects with GDB ---------------------===// // // The LLVM Compiler Infrastructure // @@ -7,9 +7,8 @@ // //===----------------------------------------------------------------------===// +#include "JITRegistrar.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ExecutionEngine/JITEventListener.h" -#include "llvm/Object/ObjectFile.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Mutex.h" @@ -17,7 +16,6 @@ #include "llvm/Support/ManagedStatic.h" using namespace llvm; -using namespace llvm::object; // This must be kept in sync with gdb/gdb/jit.h . extern "C" { @@ -62,49 +60,37 @@ extern "C" { namespace { -struct RegisteredObjectInfo { - RegisteredObjectInfo() {} - - RegisteredObjectInfo(std::size_t Size, jit_code_entry *Entry, - OwningBinary Obj) - : Size(Size), Entry(Entry), Obj(std::move(Obj)) {} - - std::size_t Size; - jit_code_entry *Entry; - OwningBinary Obj; -}; - // Buffer for an in-memory object file in executable memory -typedef llvm::DenseMap< const char*, RegisteredObjectInfo> +typedef llvm::DenseMap< const char*, + std::pair > RegisteredObjectBufferMap; /// Global access point for the JIT debugging interface designed for use with a /// singleton toolbox. Handles thread-safe registration and deregistration of /// object files that are in executable memory managed by the client of this /// class. -class GDBJITRegistrationListener : public JITEventListener { +class GDBJITRegistrar : public JITRegistrar { /// A map of in-memory object files that have been registered with the /// JIT interface. RegisteredObjectBufferMap ObjectBufferMap; public: /// Instantiates the JIT service. - GDBJITRegistrationListener() : ObjectBufferMap() {} + GDBJITRegistrar() : ObjectBufferMap() {} /// Unregisters each object that was previously registered and releases all /// internal resources. - virtual ~GDBJITRegistrationListener(); + virtual ~GDBJITRegistrar(); /// Creates an entry in the JIT registry for the buffer @p Object, /// which must contain an object file in executable memory with any /// debug information for the debugger. - void NotifyObjectEmitted(const ObjectFile &Object, - const RuntimeDyld::LoadedObjectInfo &L) override; + void registerObject(const ObjectBuffer &Object) override; /// Removes the internal registration of @p Object, and /// frees associated resources. /// Returns true if @p Object was found in ObjectBufferMap. - void NotifyFreeingObject(const ObjectFile &Object) override; + bool deregisterObject(const ObjectBuffer &Object) override; private: /// Deregister the debug info for the given object file from the debugger @@ -133,11 +119,10 @@ void NotifyDebugger(jit_code_entry* JITCodeEntry) { __jit_debug_register_code(); } -GDBJITRegistrationListener::~GDBJITRegistrationListener() { +GDBJITRegistrar::~GDBJITRegistrar() { // Free all registered object files. llvm::MutexGuard locked(*JITDebugLock); - for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(), - E = ObjectBufferMap.end(); + for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(), E = ObjectBufferMap.end(); I != E; ++I) { // Call the private method that doesn't update the map so our iterator // doesn't break. @@ -146,24 +131,14 @@ GDBJITRegistrationListener::~GDBJITRegistrationListener() { ObjectBufferMap.clear(); } -void GDBJITRegistrationListener::NotifyObjectEmitted( - const ObjectFile &Object, - const RuntimeDyld::LoadedObjectInfo &L) { - - OwningBinary DebugObj = L.getObjectForDebug(Object); - - // Bail out if debug objects aren't supported. - if (!DebugObj.getBinary()) - return; - - const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart(); - size_t Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize(); +void GDBJITRegistrar::registerObject(const ObjectBuffer &Object) { - const char *Key = Object.getMemoryBufferRef().getBufferStart(); + const char *Buffer = Object.getBufferStart(); + size_t Size = Object.getBufferSize(); - assert(Key && "Attempt to register a null object with a debugger."); + assert(Buffer && "Attempt to register a null object with a debugger."); llvm::MutexGuard locked(*JITDebugLock); - assert(ObjectBufferMap.find(Key) == ObjectBufferMap.end() && + assert(ObjectBufferMap.find(Buffer) == ObjectBufferMap.end() && "Second attempt to perform debug registration."); jit_code_entry* JITCodeEntry = new jit_code_entry(); @@ -174,27 +149,28 @@ void GDBJITRegistrationListener::NotifyObjectEmitted( JITCodeEntry->symfile_addr = Buffer; JITCodeEntry->symfile_size = Size; - ObjectBufferMap[Key] = RegisteredObjectInfo(Size, JITCodeEntry, - std::move(DebugObj)); + ObjectBufferMap[Buffer] = std::make_pair(Size, JITCodeEntry); NotifyDebugger(JITCodeEntry); } } -void GDBJITRegistrationListener::NotifyFreeingObject(const ObjectFile& Object) { - const char *Key = Object.getMemoryBufferRef().getBufferStart(); +bool GDBJITRegistrar::deregisterObject(const ObjectBuffer& Object) { + const char *Buffer = Object.getBufferStart(); llvm::MutexGuard locked(*JITDebugLock); - RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Key); + RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(Buffer); if (I != ObjectBufferMap.end()) { deregisterObjectInternal(I); ObjectBufferMap.erase(I); + return true; } + return false; } -void GDBJITRegistrationListener::deregisterObjectInternal( +void GDBJITRegistrar::deregisterObjectInternal( RegisteredObjectBufferMap::iterator I) { - jit_code_entry*& JITCodeEntry = I->second.Entry; + jit_code_entry*& JITCodeEntry = I->second.second; // Do the unregistration. { @@ -224,14 +200,14 @@ void GDBJITRegistrationListener::deregisterObjectInternal( JITCodeEntry = nullptr; } -llvm::ManagedStatic GDBRegListener; +llvm::ManagedStatic TheRegistrar; } // end namespace namespace llvm { -JITEventListener* JITEventListener::createGDBRegistrationListener() { - return &*GDBRegListener; +JITRegistrar& JITRegistrar::getGDBRegistrar() { + return *TheRegistrar; } } // namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h b/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h new file mode 100644 index 00000000000..636011f7efe --- /dev/null +++ b/lib/ExecutionEngine/RuntimeDyld/JITRegistrar.h @@ -0,0 +1,44 @@ +//===-- JITRegistrar.h - Registers objects with a debugger ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_JITREGISTRAR_H +#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_JITREGISTRAR_H + +#include "llvm/ExecutionEngine/ObjectBuffer.h" + +namespace llvm { + +/// Global access point for the JIT debugging interface. +class JITRegistrar { + virtual void anchor(); +public: + /// Instantiates the JIT service. + JITRegistrar() {} + + /// Unregisters each object that was previously registered and releases all + /// internal resources. + virtual ~JITRegistrar() {} + + /// Creates an entry in the JIT registry for the buffer @p Object, + /// which must contain an object file in executable memory with any + /// debug information for the debugger. + virtual void registerObject(const ObjectBuffer &Object) = 0; + + /// Removes the internal registration of @p Object, and + /// frees associated resources. + /// Returns true if @p Object was previously registered. + virtual bool deregisterObject(const ObjectBuffer &Object) = 0; + + /// Returns a reference to a GDB JIT registrar singleton + static JITRegistrar& getGDBRegistrar(); +}; + +} // end namespace llvm + +#endif diff --git a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h new file mode 100644 index 00000000000..9bbf6a0d809 --- /dev/null +++ b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h @@ -0,0 +1,86 @@ +//===-- ObjectImageCommon.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_LIB_EXECUTIONENGINE_RUNTIMEDYLD_OBJECTIMAGECOMMON_H +#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_OBJECTIMAGECOMMON_H + +#include "llvm/ExecutionEngine/ObjectBuffer.h" +#include "llvm/ExecutionEngine/ObjectImage.h" +#include "llvm/Object/ObjectFile.h" + +#include + +namespace llvm { + +namespace object { + class ObjectFile; +} + +class ObjectImageCommon : public ObjectImage { + ObjectImageCommon(); // = delete + ObjectImageCommon(const ObjectImageCommon &other); // = delete + void anchor() override; + +protected: + std::unique_ptr ObjFile; + + // This form of the constructor allows subclasses to use + // format-specific subclasses of ObjectFile directly + ObjectImageCommon(std::unique_ptr Input, + std::unique_ptr Obj) + : ObjectImage(std::move(Input)), ObjFile(std::move(Obj)) {} + +public: + ObjectImageCommon(std::unique_ptr Input) + : ObjectImage(std::move(Input)) { + // FIXME: error checking? createObjectFile returns an ErrorOr + // and should probably be checked for failure. + MemoryBufferRef Buf = Buffer->getMemBuffer(); + ObjFile = std::move(object::ObjectFile::createObjectFile(Buf).get()); + } + ObjectImageCommon(std::unique_ptr Input) + : ObjectImage(nullptr), ObjFile(std::move(Input)) {} + virtual ~ObjectImageCommon() { } + + object::symbol_iterator begin_symbols() const override + { return ObjFile->symbol_begin(); } + object::symbol_iterator end_symbols() const override + { return ObjFile->symbol_end(); } + + object::section_iterator begin_sections() const override + { return ObjFile->section_begin(); } + object::section_iterator end_sections() const override + { return ObjFile->section_end(); } + + /* Triple::ArchType */ unsigned getArch() const override + { return ObjFile->getArch(); } + + StringRef getData() const override { return ObjFile->getData(); } + + object::ObjectFile* getObjectFile() const override { return ObjFile.get(); } + + // Subclasses can override these methods to update the image with loaded + // addresses for sections and common symbols + void updateSectionAddress(const object::SectionRef &Sec, + uint64_t Addr) override {} + void updateSymbolAddress(const object::SymbolRef &Sym, + uint64_t Addr) override {} + + // Subclasses can override these methods to provide JIT debugging support + void registerWithDebugger() override {} + void deregisterWithDebugger() override {} +}; + +} // end namespace llvm + +#endif diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index af9a80504d5..c7c67f6a1e4 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -12,6 +12,8 @@ //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/RuntimeDyld.h" +#include "JITRegistrar.h" +#include "ObjectImageCommon.h" #include "RuntimeDyldCheckerImpl.h" #include "RuntimeDyldELF.h" #include "RuntimeDyldImpl.h" @@ -28,8 +30,10 @@ using namespace llvm::object; // Empty out-of-line virtual destructor as the key function. RuntimeDyldImpl::~RuntimeDyldImpl() {} -// Pin LoadedObjectInfo's vtables to this file. -void RuntimeDyld::LoadedObjectInfo::anchor() {} +// Pin the JITRegistrar's and ObjectImage*'s vtables to this file. +void JITRegistrar::anchor() {} +void ObjectImage::anchor() {} +void ObjectImageCommon::anchor() {} namespace llvm { @@ -135,23 +139,22 @@ static std::error_code getOffset(const SymbolRef &Sym, uint64_t &Result) { return object_error::success; } -std::pair -RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { +std::unique_ptr +RuntimeDyldImpl::loadObject(std::unique_ptr Obj) { MutexGuard locked(lock); - // Grab the first Section ID. We'll use this later to construct the underlying - // range for the returned LoadedObjectInfo. - unsigned SectionsAddedBeginIdx = Sections.size(); + if (!Obj) + return nullptr; // Save information about our target - Arch = (Triple::ArchType)Obj.getArch(); - IsTargetLittleEndian = Obj.isLittleEndian(); + Arch = (Triple::ArchType)Obj->getArch(); + IsTargetLittleEndian = Obj->getObjectFile()->isLittleEndian(); // Compute the memory size required to load all sections to be loaded // and pass this information to the memory manager if (MemMgr->needsToReserveAllocationSpace()) { uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0; - computeTotalAllocSize(Obj, CodeSize, DataSizeRO, DataSizeRW); + computeTotalAllocSize(*Obj, CodeSize, DataSizeRO, DataSizeRW); MemMgr->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW); } @@ -167,7 +170,7 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { // Parse symbols DEBUG(dbgs() << "Parse symbols:\n"); - for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E; + for (symbol_iterator I = Obj->begin_symbols(), E = Obj->end_symbols(); I != E; ++I) { object::SymbolRef::Type SymType; StringRef Name; @@ -193,15 +196,15 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { SymType == object::SymbolRef::ST_Unknown) { uint64_t SectOffset; StringRef SectionData; - section_iterator SI = Obj.section_end(); + section_iterator SI = Obj->end_sections(); Check(getOffset(*I, SectOffset)); Check(I->getSection(SI)); - if (SI == Obj.section_end()) + if (SI == Obj->end_sections()) continue; Check(SI->getContents(SectionData)); bool IsCode = SI->isText(); unsigned SectionID = - findOrEmitSection(Obj, *SI, IsCode, LocalSections); + findOrEmitSection(*Obj, *SI, IsCode, LocalSections); LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset); DEBUG(dbgs() << "\tOffset: " << format("%p", (uintptr_t)SectOffset) << " flags: " << Flags << " SID: " << SectionID); @@ -213,11 +216,11 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { // Allocate common symbols if (CommonSize != 0) - emitCommonSymbols(Obj, CommonSymbols, CommonSize, GlobalSymbolTable); + emitCommonSymbols(*Obj, CommonSymbols, CommonSize, GlobalSymbolTable); // Parse and process relocations DEBUG(dbgs() << "Parse relocations:\n"); - for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end(); + for (section_iterator SI = Obj->begin_sections(), SE = Obj->end_sections(); SI != SE; ++SI) { unsigned SectionID = 0; StubMap Stubs; @@ -231,25 +234,23 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { bool IsCode = RelocatedSection->isText(); SectionID = - findOrEmitSection(Obj, *RelocatedSection, IsCode, LocalSections); + findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections); DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n"); for (; I != E;) - I = processRelocationRef(SectionID, I, Obj, LocalSections, LocalSymbols, + I = processRelocationRef(SectionID, I, *Obj, LocalSections, LocalSymbols, Stubs); // If there is an attached checker, notify it about the stubs for this // section so that they can be verified. if (Checker) - Checker->registerStubMap(Obj.getFileName(), SectionID, Stubs); + Checker->registerStubMap(Obj->getImageName(), SectionID, Stubs); } // Give the subclasses a chance to tie-up any loose ends. - finalizeLoad(Obj, LocalSections); - - unsigned SectionsAddedEndIdx = Sections.size(); + finalizeLoad(*Obj, LocalSections); - return std::make_pair(SectionsAddedBeginIdx, SectionsAddedEndIdx); + return Obj; } // A helper method for computeTotalAllocSize. @@ -269,7 +270,7 @@ computeAllocationSizeForSections(std::vector &SectionSizes, // Compute an upper bound of the memory size that is required to load all // sections -void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, +void RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj, uint64_t &CodeSize, uint64_t &DataSizeRO, uint64_t &DataSizeRW) { @@ -281,7 +282,7 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, // Collect sizes of all sections to be loaded; // also determine the max alignment of all sections - for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end(); + for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections(); SI != SE; ++SI) { const SectionRef &Section = *SI; @@ -327,7 +328,7 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, // Compute the size of all common symbols uint64_t CommonSize = 0; - for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E; + for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E; ++I) { uint32_t Flags = I->getFlags(); if (Flags & SymbolRef::SF_Common) { @@ -352,7 +353,7 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, } // compute stub buffer size for the given section -unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj, +unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj, const SectionRef &Section) { unsigned StubSize = getMaxStubSize(); if (StubSize == 0) { @@ -362,7 +363,7 @@ unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj, // necessary section allocation size in loadObject by walking all the sections // once. unsigned StubBufSize = 0; - for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end(); + for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections(); SI != SE; ++SI) { section_iterator RelSecI = SI->getRelocatedSection(); if (!(RelSecI == Section)) @@ -417,7 +418,7 @@ void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst, } } -void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj, +void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj, const CommonSymbolMap &CommonSymbols, uint64_t TotalSize, SymbolTableMap &SymbolTable) { @@ -449,13 +450,14 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj, DEBUG(dbgs() << "Allocating common symbol " << Name << " address " << format("%p\n", Addr)); } + Obj.updateSymbolAddress(it->first, (uint64_t)Addr); SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset); Offset += Size; Addr += Size; } } -unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj, +unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, const SectionRef &Section, bool IsCode) { StringRef data; @@ -519,6 +521,7 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj, << " new addr: " << format("%p", Addr) << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize << " Allocate: " << Allocate << "\n"); + Obj.updateSectionAddress(Section, (uint64_t)Addr); } else { // Even if we didn't load the section, we need to record an entry for it // to handle later processing (and by 'handle' I mean don't do anything @@ -534,12 +537,12 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj, Sections.push_back(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData)); if (Checker) - Checker->registerSection(Obj.getFileName(), SectionID); + Checker->registerSection(Obj.getImageName(), SectionID); return SectionID; } -unsigned RuntimeDyldImpl::findOrEmitSection(const ObjectFile &Obj, +unsigned RuntimeDyldImpl::findOrEmitSection(ObjectImage &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections) { @@ -736,16 +739,6 @@ void RuntimeDyldImpl::resolveExternalSymbols() { //===----------------------------------------------------------------------===// // RuntimeDyld class implementation - -uint64_t RuntimeDyld::LoadedObjectInfo::getSectionLoadAddress( - StringRef SectionName) const { - for (unsigned I = BeginIdx; I != EndIdx; ++I) - if (RTDyld.Sections[I].Name == SectionName) - return RTDyld.Sections[I].LoadAddress; - - return 0; -} - RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) { // FIXME: There's a potential issue lurking here if a single instance of // RuntimeDyld is used to load multiple objects. The current implementation @@ -779,23 +772,78 @@ createRuntimeDyldMachO(Triple::ArchType Arch, RTDyldMemoryManager *MM, return Dyld; } -std::unique_ptr -RuntimeDyld::loadObject(const ObjectFile &Obj) { - if (!Dyld) { - if (Obj.isELF()) +std::unique_ptr +RuntimeDyld::loadObject(std::unique_ptr InputObject) { + std::unique_ptr InputImage; + + ObjectFile &Obj = *InputObject; + + if (InputObject->isELF()) { + InputImage.reset(RuntimeDyldELF::createObjectImageFromFile(std::move(InputObject))); + if (!Dyld) Dyld = createRuntimeDyldELF(MM, ProcessAllSections, Checker); - else if (Obj.isMachO()) + } else if (InputObject->isMachO()) { + InputImage.reset(RuntimeDyldMachO::createObjectImageFromFile(std::move(InputObject))); + if (!Dyld) Dyld = createRuntimeDyldMachO( - static_cast(Obj.getArch()), MM, - ProcessAllSections, Checker); - else - report_fatal_error("Incompatible object format!"); + static_cast(InputImage->getArch()), MM, + ProcessAllSections, Checker); + } else + report_fatal_error("Incompatible object format!"); + + if (!Dyld->isCompatibleFile(&Obj)) + report_fatal_error("Incompatible object format!"); + + return Dyld->loadObject(std::move(InputImage)); +} + +std::unique_ptr +RuntimeDyld::loadObject(std::unique_ptr InputBuffer) { + std::unique_ptr InputImage; + sys::fs::file_magic Type = sys::fs::identify_magic(InputBuffer->getBuffer()); + auto *InputBufferPtr = InputBuffer.get(); + + switch (Type) { + case sys::fs::file_magic::elf: + case sys::fs::file_magic::elf_relocatable: + case sys::fs::file_magic::elf_executable: + case sys::fs::file_magic::elf_shared_object: + case sys::fs::file_magic::elf_core: + InputImage = RuntimeDyldELF::createObjectImage(std::move(InputBuffer)); + if (!Dyld) + Dyld = createRuntimeDyldELF(MM, ProcessAllSections, Checker); + break; + case sys::fs::file_magic::macho_object: + case sys::fs::file_magic::macho_executable: + case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: + case sys::fs::file_magic::macho_core: + case sys::fs::file_magic::macho_preload_executable: + case sys::fs::file_magic::macho_dynamically_linked_shared_lib: + case sys::fs::file_magic::macho_dynamic_linker: + case sys::fs::file_magic::macho_bundle: + case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: + case sys::fs::file_magic::macho_dsym_companion: + InputImage = RuntimeDyldMachO::createObjectImage(std::move(InputBuffer)); + if (!Dyld) + Dyld = createRuntimeDyldMachO( + static_cast(InputImage->getArch()), MM, + ProcessAllSections, Checker); + break; + case sys::fs::file_magic::unknown: + case sys::fs::file_magic::bitcode: + case sys::fs::file_magic::archive: + case sys::fs::file_magic::coff_object: + case sys::fs::file_magic::coff_import_library: + case sys::fs::file_magic::pecoff_executable: + case sys::fs::file_magic::macho_universal_binary: + case sys::fs::file_magic::windows_resource: + report_fatal_error("Incompatible object format!"); } - if (!Dyld->isCompatibleFile(Obj)) + if (!Dyld->isCompatibleFormat(InputBufferPtr)) report_fatal_error("Incompatible object format!"); - return Dyld->loadObject(Obj); + return Dyld->loadObject(std::move(InputImage)); } void *RuntimeDyld::getSymbolAddress(StringRef Name) const { diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index d213cc93793..d95cffef03f 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -12,23 +12,27 @@ //===----------------------------------------------------------------------===// #include "RuntimeDyldELF.h" +#include "JITRegistrar.h" +#include "ObjectImageCommon.h" #include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" -#include "llvm/MC/MCStreamer.h" +#include "llvm/ExecutionEngine/ObjectBuffer.h" +#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/TargetRegistry.h" using namespace llvm; using namespace llvm::object; #define DEBUG_TYPE "dyld" +namespace { + static inline std::error_code check(std::error_code Err) { if (Err) { report_fatal_error(Err.message()); @@ -36,8 +40,6 @@ static inline std::error_code check(std::error_code Err) { return Err; } -namespace { - template class DyldELFObject : public ELFObjectFile { LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) @@ -50,12 +52,16 @@ template class DyldELFObject : public ELFObjectFile { typedef typename ELFDataTypeTypedefHelper::value_type addr_type; + std::unique_ptr UnderlyingFile; + public: + DyldELFObject(std::unique_ptr UnderlyingFile, + MemoryBufferRef Wrapper, std::error_code &ec); + DyldELFObject(MemoryBufferRef Wrapper, std::error_code &ec); void updateSectionAddress(const SectionRef &Sec, uint64_t Addr); - - void updateSymbolAddress(const SymbolRef &SymRef, uint64_t Addr); + void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr); // Methods for type inquiry through isa, cast and dyn_cast static inline bool classof(const Binary *v) { @@ -65,10 +71,42 @@ public: static inline bool classof(const ELFObjectFile *v) { return v->isDyldType(); } - }; +template class ELFObjectImage : public ObjectImageCommon { + bool Registered; + +public: + ELFObjectImage(std::unique_ptr Input, + std::unique_ptr> Obj) + : ObjectImageCommon(std::move(Input), std::move(Obj)), Registered(false) { + } + + virtual ~ELFObjectImage() { + if (Registered) + deregisterWithDebugger(); + } + + // Subclasses can override these methods to update the image with loaded + // addresses for sections and common symbols + void updateSectionAddress(const SectionRef &Sec, uint64_t Addr) override { + static_cast*>(getObjectFile()) + ->updateSectionAddress(Sec, Addr); + } + + void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr) override { + static_cast*>(getObjectFile()) + ->updateSymbolAddress(Sym, Addr); + } + void registerWithDebugger() override { + JITRegistrar::getGDBRegistrar().registerObject(*Buffer); + Registered = true; + } + void deregisterWithDebugger() override { + JITRegistrar::getGDBRegistrar().deregisterObject(*Buffer); + } +}; // The MemoryBuffer passed into this constructor is just a wrapper around the // actual memory. Ultimately, the Binary parent class will take ownership of @@ -79,6 +117,14 @@ DyldELFObject::DyldELFObject(MemoryBufferRef Wrapper, std::error_code &EC) this->isDyldELFObject = true; } +template +DyldELFObject::DyldELFObject(std::unique_ptr UnderlyingFile, + MemoryBufferRef Wrapper, std::error_code &EC) + : ELFObjectFile(Wrapper, EC), + UnderlyingFile(std::move(UnderlyingFile)) { + this->isDyldELFObject = true; +} + template void DyldELFObject::updateSectionAddress(const SectionRef &Sec, uint64_t Addr) { @@ -103,89 +149,10 @@ void DyldELFObject::updateSymbolAddress(const SymbolRef &SymRef, sym->st_value = static_cast(Addr); } -class LoadedELFObjectInfo : public RuntimeDyld::LoadedObjectInfo { -public: - LoadedELFObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx, - unsigned EndIdx) - : RuntimeDyld::LoadedObjectInfo(RTDyld, BeginIdx, EndIdx) {} - - OwningBinary - getObjectForDebug(const ObjectFile &Obj) const override; -}; - -template -std::unique_ptr> -createRTDyldELFObject(MemoryBufferRef Buffer, - const LoadedELFObjectInfo &L, - std::error_code &ec) { - typedef typename ELFFile::Elf_Shdr Elf_Shdr; - typedef typename ELFDataTypeTypedefHelper::value_type addr_type; - - std::unique_ptr> Obj = - llvm::make_unique>(Buffer, ec); - - // Iterate over all sections in the object. - for (const auto &Sec : Obj->sections()) { - StringRef SectionName; - Sec.getName(SectionName); - if (SectionName != "") { - DataRefImpl ShdrRef = Sec.getRawDataRefImpl(); - Elf_Shdr *shdr = const_cast( - reinterpret_cast(ShdrRef.p)); - - if (uint64_t SecLoadAddr = L.getSectionLoadAddress(SectionName)) { - // This assumes that the address passed in matches the target address - // bitness. The template-based type cast handles everything else. - shdr->sh_addr = static_cast(SecLoadAddr); - } - } - } - - return Obj; -} - -OwningBinary createELFDebugObject(const ObjectFile &Obj, - const LoadedELFObjectInfo &L) { - assert(Obj.isELF() && "Not an ELF object file."); - - std::unique_ptr Buffer = - MemoryBuffer::getMemBufferCopy(Obj.getData(), Obj.getFileName()); - - std::error_code ec; - - std::unique_ptr DebugObj; - if (Obj.getBytesInAddress() == 4 && Obj.isLittleEndian()) { - typedef ELFType ELF32LE; - DebugObj = createRTDyldELFObject(Buffer->getMemBufferRef(), L, ec); - } else if (Obj.getBytesInAddress() == 4 && !Obj.isLittleEndian()) { - typedef ELFType ELF32BE; - DebugObj = createRTDyldELFObject(Buffer->getMemBufferRef(), L, ec); - } else if (Obj.getBytesInAddress() == 8 && !Obj.isLittleEndian()) { - typedef ELFType ELF64BE; - DebugObj = createRTDyldELFObject(Buffer->getMemBufferRef(), L, ec); - } else if (Obj.getBytesInAddress() == 8 && Obj.isLittleEndian()) { - typedef ELFType ELF64LE; - DebugObj = createRTDyldELFObject(Buffer->getMemBufferRef(), L, ec); - } else - llvm_unreachable("Unexpected ELF format"); - - assert(!ec && "Could not construct copy ELF object file"); - - return OwningBinary(std::move(DebugObj), std::move(Buffer)); -} - -OwningBinary -LoadedELFObjectInfo::getObjectForDebug(const ObjectFile &Obj) const { - return createELFDebugObject(Obj, *this); -} - } // namespace namespace llvm { -RuntimeDyldELF::RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {} -RuntimeDyldELF::~RuntimeDyldELF() {} - void RuntimeDyldELF::registerEHFrames() { if (!MemMgr) return; @@ -213,14 +180,83 @@ void RuntimeDyldELF::deregisterEHFrames() { RegisteredEHFrameSections.clear(); } -std::unique_ptr -RuntimeDyldELF::loadObject(const object::ObjectFile &O) { - unsigned SectionStartIdx, SectionEndIdx; - std::tie(SectionStartIdx, SectionEndIdx) = loadObjectImpl(O); - return llvm::make_unique(*this, SectionStartIdx, - SectionEndIdx); +ObjectImage * +RuntimeDyldELF::createObjectImageFromFile(std::unique_ptr ObjFile) { + if (!ObjFile) + return nullptr; + + std::error_code ec; + MemoryBufferRef Buffer = ObjFile->getMemoryBufferRef(); + + if (ObjFile->getBytesInAddress() == 4 && ObjFile->isLittleEndian()) { + auto Obj = + llvm::make_unique>>( + std::move(ObjFile), Buffer, ec); + return new ELFObjectImage>( + nullptr, std::move(Obj)); + } else if (ObjFile->getBytesInAddress() == 4 && !ObjFile->isLittleEndian()) { + auto Obj = + llvm::make_unique>>( + std::move(ObjFile), Buffer, ec); + return new ELFObjectImage>(nullptr, std::move(Obj)); + } else if (ObjFile->getBytesInAddress() == 8 && !ObjFile->isLittleEndian()) { + auto Obj = llvm::make_unique>>( + std::move(ObjFile), Buffer, ec); + return new ELFObjectImage>(nullptr, + std::move(Obj)); + } else if (ObjFile->getBytesInAddress() == 8 && ObjFile->isLittleEndian()) { + auto Obj = + llvm::make_unique>>( + std::move(ObjFile), Buffer, ec); + return new ELFObjectImage>( + nullptr, std::move(Obj)); + } else + llvm_unreachable("Unexpected ELF format"); } +std::unique_ptr +RuntimeDyldELF::createObjectImage(std::unique_ptr Buffer) { + if (Buffer->getBufferSize() < ELF::EI_NIDENT) + llvm_unreachable("Unexpected ELF object size"); + std::pair Ident = + std::make_pair((uint8_t)Buffer->getBufferStart()[ELF::EI_CLASS], + (uint8_t)Buffer->getBufferStart()[ELF::EI_DATA]); + std::error_code ec; + + MemoryBufferRef Buf = Buffer->getMemBuffer(); + + if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) { + auto Obj = + llvm::make_unique>>( + Buf, ec); + return llvm::make_unique< + ELFObjectImage>>(std::move(Buffer), + std::move(Obj)); + } + if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) { + auto Obj = + llvm::make_unique>>(Buf, + ec); + return llvm::make_unique>>( + std::move(Buffer), std::move(Obj)); + } + if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) { + auto Obj = llvm::make_unique>>( + Buf, ec); + return llvm::make_unique>>( + std::move(Buffer), std::move(Obj)); + } + assert(Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB && + "Unexpected ELF format"); + auto Obj = + llvm::make_unique>>(Buf, + ec); + return llvm::make_unique>>( + std::move(Buffer), std::move(Obj)); +} + +RuntimeDyldELF::~RuntimeDyldELF() {} + void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend, @@ -579,7 +615,7 @@ void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section, } // Return the .TOC. section and offset. -void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj, +void RuntimeDyldELF::findPPC64TOCSection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections, RelocationValueRef &Rel) { // Set a default SectionID in case we do not find a TOC section below. @@ -592,7 +628,7 @@ void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj, // The TOC consists of sections .got, .toc, .tocbss, .plt in that // order. The TOC starts where the first of these sections starts. - for (section_iterator si = Obj.section_begin(), se = Obj.section_end(); + for (section_iterator si = Obj.begin_sections(), se = Obj.end_sections(); si != se; ++si) { StringRef SectionName; @@ -614,15 +650,15 @@ void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj, // Returns the sections and offset associated with the ODP entry referenced // by Symbol. -void RuntimeDyldELF::findOPDEntrySection(const ObjectFile &Obj, +void RuntimeDyldELF::findOPDEntrySection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections, RelocationValueRef &Rel) { // Get the ELF symbol value (st_value) to compare with Relocation offset in // .opd entries - for (section_iterator si = Obj.section_begin(), se = Obj.section_end(); + for (section_iterator si = Obj.begin_sections(), se = Obj.end_sections(); si != se; ++si) { section_iterator RelSecI = si->getRelocatedSection(); - if (RelSecI == Obj.section_end()) + if (RelSecI == Obj.end_sections()) continue; StringRef RelSectionName; @@ -664,7 +700,7 @@ void RuntimeDyldELF::findOPDEntrySection(const ObjectFile &Obj, if (Rel.Addend != (int64_t)TargetSymbolOffset) continue; - section_iterator tsi(Obj.section_end()); + section_iterator tsi(Obj.end_sections()); check(TargetSymbol->getSection(tsi)); bool IsCode = tsi->isText(); Rel.SectionID = findOrEmitSection(Obj, (*tsi), IsCode, LocalSections); @@ -899,8 +935,7 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, } relocation_iterator RuntimeDyldELF::processRelocationRef( - unsigned SectionID, relocation_iterator RelI, - const ObjectFile &Obj, + unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, StubMap &Stubs) { uint64_t RelType; @@ -911,7 +946,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef( // Obtain the symbol name which is referenced in the relocation StringRef TargetName; - if (Symbol != Obj.symbol_end()) + if (Symbol != Obj.end_symbols()) Symbol->getName(TargetName); DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend << " TargetName: " << TargetName << "\n"); @@ -919,7 +954,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef( // First search for the symbol in the local symbol table SymbolTableMap::const_iterator lsi = Symbols.end(); SymbolRef::Type SymType = SymbolRef::ST_Unknown; - if (Symbol != Obj.symbol_end()) { + if (Symbol != Obj.end_symbols()) { lsi = Symbols.find(TargetName.data()); Symbol->getType(SymType); } @@ -930,7 +965,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef( } else { // Search for the symbol in the global symbol table SymbolTableMap::const_iterator gsi = GlobalSymbolTable.end(); - if (Symbol != Obj.symbol_end()) + if (Symbol != Obj.end_symbols()) gsi = GlobalSymbolTable.find(TargetName.data()); if (gsi != GlobalSymbolTable.end()) { Value.SectionID = gsi->second.first; @@ -942,9 +977,9 @@ relocation_iterator RuntimeDyldELF::processRelocationRef( // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously // and can be changed by another developers. Maybe best way is add // a new symbol type ST_Section to SymbolRef and use it. - section_iterator si(Obj.section_end()); + section_iterator si(Obj.end_sections()); Symbol->getSection(si); - if (si == Obj.section_end()) + if (si == Obj.end_sections()) llvm_unreachable("Symbol section not found, bad object file format!"); DEBUG(dbgs() << "\t\tThis is section symbol\n"); bool isCode = si->isText(); @@ -1100,7 +1135,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef( if (RelType == ELF::R_PPC64_REL24) { // Determine ABI variant in use for this object. unsigned AbiVariant; - Obj.getPlatformFlags(AbiVariant); + Obj.getObjectFile()->getPlatformFlags(AbiVariant); AbiVariant &= ELF::EF_PPC64_ABI; // A PPC branch relocation will need a stub function if the target is // an external symbol (Symbol::ST_Unknown) or if the target address @@ -1460,7 +1495,7 @@ uint64_t RuntimeDyldELF::findGOTEntry(uint64_t LoadAddress, uint64_t Offset) { return 0; } -void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj, +void RuntimeDyldELF::finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) { // If necessary, allocate the global offset table if (MemMgr) { @@ -1498,8 +1533,15 @@ void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj, } } -bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile &Obj) const { - return Obj.isELF(); +bool RuntimeDyldELF::isCompatibleFormat(const ObjectBuffer *Buffer) const { + if (Buffer->getBufferSize() < strlen(ELF::ElfMagic)) + return false; + return (memcmp(Buffer->getBufferStart(), ELF::ElfMagic, + strlen(ELF::ElfMagic))) == 0; +} + +bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile *Obj) const { + return Obj->isELF(); } } // namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index f9c1d4db30b..4aeab819179 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -28,11 +28,9 @@ std::error_code Check(std::error_code Err) { } return Err; } - } // end anonymous namespace class RuntimeDyldELF : public RuntimeDyldImpl { - void resolveRelocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend, uint64_t SymOffset = 0); @@ -83,11 +81,9 @@ class RuntimeDyldELF : public RuntimeDyldImpl { return 1; } - void findPPC64TOCSection(const ObjectFile &Obj, - ObjSectionToIDMap &LocalSections, + void findPPC64TOCSection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections, RelocationValueRef &Rel); - void findOPDEntrySection(const ObjectFile &Obj, - ObjSectionToIDMap &LocalSections, + void findOPDEntrySection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections, RelocationValueRef &Rel); uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset); @@ -108,23 +104,24 @@ class RuntimeDyldELF : public RuntimeDyldImpl { SmallVector RegisteredEHFrameSections; public: - RuntimeDyldELF(RTDyldMemoryManager *mm); - virtual ~RuntimeDyldELF(); - - std::unique_ptr - loadObject(const object::ObjectFile &O) override; + RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {} void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override; relocation_iterator processRelocationRef(unsigned SectionID, relocation_iterator RelI, - const ObjectFile &Obj, - ObjSectionToIDMap &ObjSectionToID, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, StubMap &Stubs) override; - bool isCompatibleFile(const object::ObjectFile &Obj) const override; + bool isCompatibleFormat(const ObjectBuffer *Buffer) const override; + bool isCompatibleFile(const object::ObjectFile *Buffer) const override; void registerEHFrames() override; void deregisterEHFrames() override; - void finalizeLoad(const ObjectFile &Obj, + void finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) override; + virtual ~RuntimeDyldELF(); + + static std::unique_ptr + createObjectImage(std::unique_ptr InputBuffer); + static ObjectImage *createObjectImageFromFile(std::unique_ptr Obj); }; } // end namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 22d39408a59..69ea3b4f4e6 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Triple.h" +#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/ExecutionEngine/RuntimeDyldChecker.h" #include "llvm/Object/ObjectFile.h" @@ -36,6 +37,7 @@ using namespace llvm::object; namespace llvm { +class ObjectBuffer; class Twine; /// SectionEntry - represents a section emitted into memory by the dynamic @@ -157,7 +159,6 @@ public: }; class RuntimeDyldImpl { - friend class RuntimeDyld::LoadedObjectInfo; friend class RuntimeDyldCheckerImpl; private: @@ -295,15 +296,14 @@ protected: /// \brief Given the common symbols discovered in the object file, emit a /// new section for them and update the symbol mappings in the object and /// symbol table. - void emitCommonSymbols(const ObjectFile &Obj, - const CommonSymbolMap &CommonSymbols, + void emitCommonSymbols(ObjectImage &Obj, const CommonSymbolMap &CommonSymbols, uint64_t TotalSize, SymbolTableMap &SymbolTable); /// \brief Emits section data from the object file to the MemoryManager. /// \param IsCode if it's true then allocateCodeSection() will be /// used for emits, else allocateDataSection() will be used. /// \return SectionID. - unsigned emitSection(const ObjectFile &Obj, const SectionRef &Section, + unsigned emitSection(ObjectImage &Obj, const SectionRef &Section, bool IsCode); /// \brief Find Section in LocalSections. If the secton is not found - emit @@ -311,7 +311,7 @@ protected: /// \param IsCode if it's true then allocateCodeSection() will be /// used for emmits, else allocateDataSection() will be used. /// \return SectionID. - unsigned findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, + unsigned findOrEmitSection(ObjectImage &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections); // \brief Add a relocation entry that uses the given section. @@ -339,7 +339,7 @@ protected: /// \return Iterator to the next relocation that needs to be parsed. virtual relocation_iterator processRelocationRef(unsigned SectionID, relocation_iterator RelI, - const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, StubMap &Stubs) = 0; /// \brief Resolve relocations to external symbols. @@ -351,16 +351,13 @@ protected: // \brief Compute an upper bound of the memory that is required to load all // sections - void computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize, + void computeTotalAllocSize(ObjectImage &Obj, uint64_t &CodeSize, uint64_t &DataSizeRO, uint64_t &DataSizeRW); // \brief Compute the stub buffer size required for a section - unsigned computeSectionStubBufSize(const ObjectFile &Obj, + unsigned computeSectionStubBufSize(ObjectImage &Obj, const SectionRef &Section); - // \brief Implementation of the generic part of the loadObject algorithm. - std::pair loadObjectImpl(const object::ObjectFile &Obj); - public: RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), Checker(nullptr), ProcessAllSections(false), HasError(false) { @@ -376,8 +373,8 @@ public: this->Checker = Checker; } - virtual std::unique_ptr - loadObject(const object::ObjectFile &Obj) = 0; + std::unique_ptr + loadObject(std::unique_ptr InputObject); uint8_t* getSymbolAddress(StringRef Name) const { // FIXME: Just look up as a function for now. Overly simple of course. @@ -414,14 +411,14 @@ public: // Get the error message. StringRef getErrorString() { return ErrorStr; } - virtual bool isCompatibleFile(const ObjectFile &Obj) const = 0; + virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0; + virtual bool isCompatibleFile(const ObjectFile *Obj) const = 0; virtual void registerEHFrames(); virtual void deregisterEHFrames(); - virtual void finalizeLoad(const ObjectFile &ObjImg, - ObjSectionToIDMap &SectionMap) {} + virtual void finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) {} }; } // end namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 81020dc7712..d3d6f5d2546 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -25,22 +25,6 @@ using namespace llvm::object; #define DEBUG_TYPE "dyld" -namespace { - -class LoadedMachOObjectInfo : public RuntimeDyld::LoadedObjectInfo { -public: - LoadedMachOObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx, - unsigned EndIdx) - : RuntimeDyld::LoadedObjectInfo(RTDyld, BeginIdx, EndIdx) {} - - OwningBinary - getObjectForDebug(const ObjectFile &Obj) const override { - return OwningBinary(); - } -}; - -} - namespace llvm { int64_t RuntimeDyldMachO::memcpyAddend(const RelocationEntry &RE) const { @@ -51,12 +35,12 @@ int64_t RuntimeDyldMachO::memcpyAddend(const RelocationEntry &RE) const { } RelocationValueRef RuntimeDyldMachO::getRelocationValueRef( - const ObjectFile &BaseTObj, const relocation_iterator &RI, + ObjectImage &ObjImg, const relocation_iterator &RI, const RelocationEntry &RE, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols) { const MachOObjectFile &Obj = - static_cast(BaseTObj); + static_cast(*ObjImg.getObjectFile()); MachO::any_relocation_info RelInfo = Obj.getRelocation(RI->getRawDataRefImpl()); RelocationValueRef Value; @@ -83,7 +67,7 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef( } else { SectionRef Sec = Obj.getRelocationSection(RelInfo); bool IsCode = Sec.isText(); - Value.SectionID = findOrEmitSection(Obj, Sec, IsCode, ObjSectionToID); + Value.SectionID = findOrEmitSection(ObjImg, Sec, IsCode, ObjSectionToID); uint64_t Addr = Sec.getAddress(); Value.Offset = RE.Addend - Addr; } @@ -92,11 +76,11 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef( } void RuntimeDyldMachO::makeValueAddendPCRel(RelocationValueRef &Value, - const ObjectFile &BaseTObj, + ObjectImage &ObjImg, const relocation_iterator &RI, unsigned OffsetToNextPC) { const MachOObjectFile &Obj = - static_cast(BaseTObj); + static_cast(*ObjImg.getObjectFile()); MachO::any_relocation_info RelInfo = Obj.getRelocation(RI->getRawDataRefImpl()); @@ -141,7 +125,7 @@ RuntimeDyldMachO::getSectionByAddress(const MachOObjectFile &Obj, // Populate __pointers section. void RuntimeDyldMachO::populateIndirectSymbolPointersSection( - const MachOObjectFile &Obj, + MachOObjectFile &Obj, const SectionRef &PTSection, unsigned PTSectionID) { assert(!Obj.is64Bit() && @@ -179,12 +163,28 @@ void RuntimeDyldMachO::populateIndirectSymbolPointersSection( } } -bool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile &Obj) const { - return Obj.isMachO(); +bool +RuntimeDyldMachO::isCompatibleFormat(const ObjectBuffer *InputBuffer) const { + if (InputBuffer->getBufferSize() < 4) + return false; + StringRef Magic(InputBuffer->getBufferStart(), 4); + if (Magic == "\xFE\xED\xFA\xCE") + return true; + if (Magic == "\xCE\xFA\xED\xFE") + return true; + if (Magic == "\xFE\xED\xFA\xCF") + return true; + if (Magic == "\xCF\xFA\xED\xFE") + return true; + return false; +} + +bool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile *Obj) const { + return Obj->isMachO(); } template -void RuntimeDyldMachOCRTPBase::finalizeLoad(const ObjectFile &ObjImg, +void RuntimeDyldMachOCRTPBase::finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) { unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID; unsigned TextSID = RTDYLD_INVALID_SECTION_ID; @@ -284,7 +284,7 @@ void RuntimeDyldMachOCRTPBase::registerEHFrames() { } std::unique_ptr -RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) { +llvm::RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) { switch (Arch) { default: llvm_unreachable("Unsupported target for RuntimeDyldMachO."); @@ -296,12 +296,4 @@ RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) { } } -std::unique_ptr -RuntimeDyldMachO::loadObject(const object::ObjectFile &O) { - unsigned SectionStartIdx, SectionEndIdx; - std::tie(SectionStartIdx, SectionEndIdx) = loadObjectImpl(O); - return llvm::make_unique(*this, SectionStartIdx, - SectionEndIdx); -} - } // end namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index ff102ffea6a..7583474757d 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -14,6 +14,7 @@ #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDMACHO_H #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDMACHO_H +#include "ObjectImageCommon.h" #include "RuntimeDyldImpl.h" #include "llvm/Object/MachO.h" #include "llvm/Support/Format.h" @@ -60,11 +61,10 @@ protected: /// filled in, since immediate encodings are highly target/opcode specific. /// For targets/opcodes with simple, contiguous immediates (e.g. X86) the /// memcpyAddend method can be used to read the immediate. - RelocationEntry getRelocationEntry(unsigned SectionID, - const ObjectFile &BaseTObj, + RelocationEntry getRelocationEntry(unsigned SectionID, ObjectImage &ObjImg, const relocation_iterator &RI) const { const MachOObjectFile &Obj = - static_cast(BaseTObj); + static_cast(*ObjImg.getObjectFile()); MachO::any_relocation_info RelInfo = Obj.getRelocation(RI->getRawDataRefImpl()); @@ -87,15 +87,14 @@ protected: /// In both cases the Addend field is *NOT* fixed up to be PC-relative. That /// should be done by the caller where appropriate by calling makePCRel on /// the RelocationValueRef. - RelocationValueRef getRelocationValueRef(const ObjectFile &BaseTObj, + RelocationValueRef getRelocationValueRef(ObjectImage &ObjImg, const relocation_iterator &RI, const RelocationEntry &RE, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols); /// Make the RelocationValueRef addend PC-relative. - void makeValueAddendPCRel(RelocationValueRef &Value, - const ObjectFile &BaseTObj, + void makeValueAddendPCRel(RelocationValueRef &Value, ObjectImage &ObjImg, const relocation_iterator &RI, unsigned OffsetToNextPC); @@ -108,22 +107,31 @@ protected: // Populate __pointers section. - void populateIndirectSymbolPointersSection(const MachOObjectFile &Obj, + void populateIndirectSymbolPointersSection(MachOObjectFile &Obj, const SectionRef &PTSection, unsigned PTSectionID); public: + /// Create an ObjectImage from the given ObjectBuffer. + static std::unique_ptr + createObjectImage(std::unique_ptr InputBuffer) { + return llvm::make_unique(std::move(InputBuffer)); + } + + /// Create an ObjectImage from the given ObjectFile. + static ObjectImage * + createObjectImageFromFile(std::unique_ptr InputObject) { + return new ObjectImageCommon(std::move(InputObject)); + } /// Create a RuntimeDyldMachO instance for the given target architecture. static std::unique_ptr create(Triple::ArchType Arch, RTDyldMemoryManager *mm); - std::unique_ptr - loadObject(const object::ObjectFile &O) override; - SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; } - bool isCompatibleFile(const object::ObjectFile &Obj) const override; + bool isCompatibleFormat(const ObjectBuffer *Buffer) const override; + bool isCompatibleFile(const object::ObjectFile *Obj) const override; }; /// RuntimeDyldMachOTarget - Templated base class for generic MachO linker @@ -145,7 +153,7 @@ private: public: RuntimeDyldMachOCRTPBase(RTDyldMemoryManager *mm) : RuntimeDyldMachO(mm) {} - void finalizeLoad(const ObjectFile &Obj, + void finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) override; void registerEHFrames() override; }; diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h index 8c1efef722d..f5cf9ac29bf 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h @@ -243,11 +243,10 @@ public: relocation_iterator processRelocationRef(unsigned SectionID, relocation_iterator RelI, - const ObjectFile &BaseObjT, - ObjSectionToIDMap &ObjSectionToID, + ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, StubMap &Stubs) override { const MachOObjectFile &Obj = - static_cast(BaseObjT); + static_cast(*ObjImg.getObjectFile()); MachO::any_relocation_info RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl()); @@ -269,10 +268,10 @@ public: RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl()); } - RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI)); + RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI)); RE.Addend = decodeAddend(RE); RelocationValueRef Value( - getRelocationValueRef(Obj, RelI, RE, ObjSectionToID, Symbols)); + getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols)); assert((ExplicitAddend == 0 || RE.Addend == 0) && "Relocation has "\ "ARM64_RELOC_ADDEND and embedded addend in the instruction."); @@ -283,7 +282,7 @@ public: bool IsExtern = Obj.getPlainRelocationExternal(RelInfo); if (!IsExtern && RE.IsPCRel) - makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size); + makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size); RE.Addend = Value.Offset; @@ -360,7 +359,7 @@ public: } } - void finalizeSection(const ObjectFile &Obj, unsigned SectionID, + void finalizeSection(ObjectImage &ObjImg, unsigned SectionID, const SectionRef &Section) {} private: diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h index d7e623697bb..9766751c43d 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h @@ -49,30 +49,29 @@ public: relocation_iterator processRelocationRef(unsigned SectionID, relocation_iterator RelI, - const ObjectFile &BaseObjT, - ObjSectionToIDMap &ObjSectionToID, + ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, StubMap &Stubs) override { const MachOObjectFile &Obj = - static_cast(BaseObjT); + static_cast(*ObjImg.getObjectFile()); MachO::any_relocation_info RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl()); uint32_t RelType = Obj.getAnyRelocationType(RelInfo); if (Obj.isRelocationScattered(RelInfo)) { if (RelType == MachO::ARM_RELOC_HALF_SECTDIFF) - return processHALFSECTDIFFRelocation(SectionID, RelI, Obj, + return processHALFSECTDIFFRelocation(SectionID, RelI, ObjImg, ObjSectionToID); else return ++++RelI; } - RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI)); + RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI)); RE.Addend = decodeAddend(RE); RelocationValueRef Value( - getRelocationValueRef(Obj, RelI, RE, ObjSectionToID, Symbols)); + getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols)); if (RE.IsPCRel) - makeValueAddendPCRel(Value, Obj, RelI, 8); + makeValueAddendPCRel(Value, ObjImg, RelI, 8); if ((RE.RelType & 0xf) == MachO::ARM_RELOC_BR24) processBranchRelocation(RE, Value, Stubs); @@ -155,14 +154,15 @@ public: } } - void finalizeSection(const ObjectFile &Obj, unsigned SectionID, + void finalizeSection(ObjectImage &ObjImg, unsigned SectionID, const SectionRef &Section) { StringRef Name; Section.getName(Name); if (Name == "__nl_symbol_ptr") - populateIndirectSymbolPointersSection(cast(Obj), - Section, SectionID); + populateIndirectSymbolPointersSection( + cast(*ObjImg.getObjectFile()), + Section, SectionID); } private: @@ -199,25 +199,25 @@ private: relocation_iterator processHALFSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI, - const ObjectFile &BaseTObj, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID) { - const MachOObjectFile &MachO = - static_cast(BaseTObj); + const MachOObjectFile *MachO = + static_cast(Obj.getObjectFile()); MachO::any_relocation_info RE = - MachO.getRelocation(RelI->getRawDataRefImpl()); + MachO->getRelocation(RelI->getRawDataRefImpl()); // For a half-diff relocation the length bits actually record whether this // is a movw/movt, and whether this is arm or thumb. // Bit 0 indicates movw (b0 == 0) or movt (b0 == 1). // Bit 1 indicates arm (b1 == 0) or thumb (b1 == 1). - unsigned HalfDiffKindBits = MachO.getAnyRelocationLength(RE); + unsigned HalfDiffKindBits = MachO->getAnyRelocationLength(RE); if (HalfDiffKindBits & 0x2) llvm_unreachable("Thumb not yet supported."); SectionEntry &Section = Sections[SectionID]; - uint32_t RelocType = MachO.getAnyRelocationType(RE); - bool IsPCRel = MachO.getAnyRelocationPCRel(RE); + uint32_t RelocType = MachO->getAnyRelocationType(RE); + bool IsPCRel = MachO->getAnyRelocationPCRel(RE); uint64_t Offset; RelI->getOffset(Offset); uint8_t *LocalAddress = Section.Address + Offset; @@ -226,27 +226,27 @@ private: ++RelI; MachO::any_relocation_info RE2 = - MachO.getRelocation(RelI->getRawDataRefImpl()); - uint32_t AddrA = MachO.getScatteredRelocationValue(RE); - section_iterator SAI = getSectionByAddress(MachO, AddrA); - assert(SAI != MachO.section_end() && "Can't find section for address A"); + MachO->getRelocation(RelI->getRawDataRefImpl()); + uint32_t AddrA = MachO->getScatteredRelocationValue(RE); + section_iterator SAI = getSectionByAddress(*MachO, AddrA); + assert(SAI != MachO->section_end() && "Can't find section for address A"); uint64_t SectionABase = SAI->getAddress(); uint64_t SectionAOffset = AddrA - SectionABase; SectionRef SectionA = *SAI; bool IsCode = SectionA.isText(); uint32_t SectionAID = - findOrEmitSection(MachO, SectionA, IsCode, ObjSectionToID); + findOrEmitSection(Obj, SectionA, IsCode, ObjSectionToID); - uint32_t AddrB = MachO.getScatteredRelocationValue(RE2); - section_iterator SBI = getSectionByAddress(MachO, AddrB); - assert(SBI != MachO.section_end() && "Can't find section for address B"); + uint32_t AddrB = MachO->getScatteredRelocationValue(RE2); + section_iterator SBI = getSectionByAddress(*MachO, AddrB); + assert(SBI != MachO->section_end() && "Can't find section for address B"); uint64_t SectionBBase = SBI->getAddress(); uint64_t SectionBOffset = AddrB - SectionBBase; SectionRef SectionB = *SBI; uint32_t SectionBID = - findOrEmitSection(MachO, SectionB, IsCode, ObjSectionToID); + findOrEmitSection(Obj, SectionB, IsCode, ObjSectionToID); - uint32_t OtherHalf = MachO.getAnyRelocationAddress(RE2) & 0xffff; + uint32_t OtherHalf = MachO->getAnyRelocationAddress(RE2) & 0xffff; unsigned Shift = (HalfDiffKindBits & 0x1) ? 16 : 0; uint32_t FullImmVal = (Immediate << Shift) | (OtherHalf << (16 - Shift)); int64_t Addend = FullImmVal - (AddrA - AddrB); diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h index 78ac911f442..258b8476d42 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h @@ -31,11 +31,10 @@ public: relocation_iterator processRelocationRef(unsigned SectionID, relocation_iterator RelI, - const ObjectFile &BaseObjT, - ObjSectionToIDMap &ObjSectionToID, + ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, StubMap &Stubs) override { const MachOObjectFile &Obj = - static_cast(BaseObjT); + static_cast(*ObjImg.getObjectFile()); MachO::any_relocation_info RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl()); uint32_t RelType = Obj.getAnyRelocationType(RelInfo); @@ -43,18 +42,18 @@ public: if (Obj.isRelocationScattered(RelInfo)) { if (RelType == MachO::GENERIC_RELOC_SECTDIFF || RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) - return processSECTDIFFRelocation(SectionID, RelI, Obj, + return processSECTDIFFRelocation(SectionID, RelI, ObjImg, ObjSectionToID); else if (RelType == MachO::GENERIC_RELOC_VANILLA) - return processI386ScatteredVANILLA(SectionID, RelI, Obj, + return processI386ScatteredVANILLA(SectionID, RelI, ObjImg, ObjSectionToID); llvm_unreachable("Unhandled scattered relocation."); } - RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI)); + RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI)); RE.Addend = memcpyAddend(RE); RelocationValueRef Value( - getRelocationValueRef(Obj, RelI, RE, ObjSectionToID, Symbols)); + getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols)); // Addends for external, PC-rel relocations on i386 point back to the zero // offset. Calculate the final offset from the relocation target instead. @@ -67,7 +66,7 @@ public: // Value.Addend += RelocAddr + 4; // } if (RE.IsPCRel) - makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size); + makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size); RE.Addend = Value.Offset; @@ -111,32 +110,34 @@ public: } } - void finalizeSection(const ObjectFile &Obj, unsigned SectionID, + void finalizeSection(ObjectImage &ObjImg, unsigned SectionID, const SectionRef &Section) { StringRef Name; Section.getName(Name); if (Name == "__jump_table") - populateJumpTable(cast(Obj), Section, SectionID); + populateJumpTable(cast(*ObjImg.getObjectFile()), Section, + SectionID); else if (Name == "__pointers") - populateIndirectSymbolPointersSection(cast(Obj), - Section, SectionID); + populateIndirectSymbolPointersSection( + cast(*ObjImg.getObjectFile()), + Section, SectionID); } private: relocation_iterator processSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI, - const ObjectFile &BaseObjT, + ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID) { - const MachOObjectFile &Obj = - static_cast(BaseObjT); + const MachOObjectFile *MachO = + static_cast(Obj.getObjectFile()); MachO::any_relocation_info RE = - Obj.getRelocation(RelI->getRawDataRefImpl()); + MachO->getRelocation(RelI->getRawDataRefImpl()); SectionEntry &Section = Sections[SectionID]; - uint32_t RelocType = Obj.getAnyRelocationType(RE); - bool IsPCRel = Obj.getAnyRelocationPCRel(RE); - unsigned Size = Obj.getAnyRelocationLength(RE); + uint32_t RelocType = MachO->getAnyRelocationType(RE); + bool IsPCRel = MachO->getAnyRelocationPCRel(RE); + unsigned Size = MachO->getAnyRelocationLength(RE); uint64_t Offset; RelI->getOffset(Offset); uint8_t *LocalAddress = Section.Address + Offset; @@ -145,11 +146,11 @@ private: ++RelI; MachO::any_relocation_info RE2 = - Obj.getRelocation(RelI->getRawDataRefImpl()); + MachO->getRelocation(RelI->getRawDataRefImpl()); - uint32_t AddrA = Obj.getScatteredRelocationValue(RE); - section_iterator SAI = getSectionByAddress(Obj, AddrA); - assert(SAI != Obj.section_end() && "Can't find section for address A"); + uint32_t AddrA = MachO->getScatteredRelocationValue(RE); + section_iterator SAI = getSectionByAddress(*MachO, AddrA); + assert(SAI != MachO->section_end() && "Can't find section for address A"); uint64_t SectionABase = SAI->getAddress(); uint64_t SectionAOffset = AddrA - SectionABase; SectionRef SectionA = *SAI; @@ -157,9 +158,9 @@ private: uint32_t SectionAID = findOrEmitSection(Obj, SectionA, IsCode, ObjSectionToID); - uint32_t AddrB = Obj.getScatteredRelocationValue(RE2); - section_iterator SBI = getSectionByAddress(Obj, AddrB); - assert(SBI != Obj.section_end() && "Can't find section for address B"); + uint32_t AddrB = MachO->getScatteredRelocationValue(RE2); + section_iterator SBI = getSectionByAddress(*MachO, AddrB); + assert(SBI != MachO->section_end() && "Can't find section for address B"); uint64_t SectionBBase = SBI->getAddress(); uint64_t SectionBOffset = AddrB - SectionBBase; SectionRef SectionB = *SBI; @@ -185,27 +186,26 @@ private: } relocation_iterator processI386ScatteredVANILLA( - unsigned SectionID, relocation_iterator RelI, - const ObjectFile &BaseObjT, + unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj, RuntimeDyldMachO::ObjSectionToIDMap &ObjSectionToID) { - const MachOObjectFile &Obj = - static_cast(BaseObjT); + const MachOObjectFile *MachO = + static_cast(Obj.getObjectFile()); MachO::any_relocation_info RE = - Obj.getRelocation(RelI->getRawDataRefImpl()); + MachO->getRelocation(RelI->getRawDataRefImpl()); SectionEntry &Section = Sections[SectionID]; - uint32_t RelocType = Obj.getAnyRelocationType(RE); - bool IsPCRel = Obj.getAnyRelocationPCRel(RE); - unsigned Size = Obj.getAnyRelocationLength(RE); + uint32_t RelocType = MachO->getAnyRelocationType(RE); + bool IsPCRel = MachO->getAnyRelocationPCRel(RE); + unsigned Size = MachO->getAnyRelocationLength(RE); uint64_t Offset; RelI->getOffset(Offset); uint8_t *LocalAddress = Section.Address + Offset; unsigned NumBytes = 1 << Size; int64_t Addend = readBytesUnaligned(LocalAddress, NumBytes); - unsigned SymbolBaseAddr = Obj.getScatteredRelocationValue(RE); - section_iterator TargetSI = getSectionByAddress(Obj, SymbolBaseAddr); - assert(TargetSI != Obj.section_end() && "Can't find section for symbol"); + unsigned SymbolBaseAddr = MachO->getScatteredRelocationValue(RE); + section_iterator TargetSI = getSectionByAddress(*MachO, SymbolBaseAddr); + assert(TargetSI != MachO->section_end() && "Can't find section for symbol"); uint64_t SectionBaseAddr = TargetSI->getAddress(); SectionRef TargetSection = *TargetSI; bool IsCode = TargetSection.isText(); @@ -221,7 +221,7 @@ private: } // Populate stubs in __jump_table section. - void populateJumpTable(const MachOObjectFile &Obj, const SectionRef &JTSection, + void populateJumpTable(MachOObjectFile &Obj, const SectionRef &JTSection, unsigned JTSectionID) { assert(!Obj.is64Bit() && "__jump_table section not supported in 64-bit MachO."); diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h index a38867e7b6a..84d9e809a17 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h @@ -31,25 +31,24 @@ public: relocation_iterator processRelocationRef(unsigned SectionID, relocation_iterator RelI, - const ObjectFile &BaseObjT, - ObjSectionToIDMap &ObjSectionToID, + ObjectImage &ObjImg, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, StubMap &Stubs) override { const MachOObjectFile &Obj = - static_cast(BaseObjT); + static_cast(*ObjImg.getObjectFile()); MachO::any_relocation_info RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl()); assert(!Obj.isRelocationScattered(RelInfo) && "Scattered relocations not supported on X86_64"); - RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI)); + RelocationEntry RE(getRelocationEntry(SectionID, ObjImg, RelI)); RE.Addend = memcpyAddend(RE); RelocationValueRef Value( - getRelocationValueRef(Obj, RelI, RE, ObjSectionToID, Symbols)); + getRelocationValueRef(ObjImg, RelI, RE, ObjSectionToID, Symbols)); bool IsExtern = Obj.getPlainRelocationExternal(RelInfo); if (!IsExtern && RE.IsPCRel) - makeValueAddendPCRel(Value, Obj, RelI, 1 << RE.Size); + makeValueAddendPCRel(Value, ObjImg, RelI, 1 << RE.Size); if (RE.RelType == MachO::X86_64_RELOC_GOT || RE.RelType == MachO::X86_64_RELOC_GOT_LOAD) @@ -98,7 +97,7 @@ public: } } - void finalizeSection(const ObjectFile &Obj, unsigned SectionID, + void finalizeSection(ObjectImage &ObjImg, unsigned SectionID, const SectionRef &Section) {} private: diff --git a/tools/lli/RemoteMemoryManager.cpp b/tools/lli/RemoteMemoryManager.cpp index 47da8fb60c9..5a135eabd73 100644 --- a/tools/lli/RemoteMemoryManager.cpp +++ b/tools/lli/RemoteMemoryManager.cpp @@ -14,6 +14,7 @@ #include "RemoteMemoryManager.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Format.h" @@ -77,7 +78,7 @@ sys::MemoryBlock RemoteMemoryManager::allocateSection(uintptr_t Size) { } void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE, - const object::ObjectFile &Obj) { + const ObjectImage *Obj) { // The client should have called setRemoteTarget() before triggering any // code generation. assert(Target); diff --git a/tools/lli/RemoteMemoryManager.h b/tools/lli/RemoteMemoryManager.h index 895bcdac4d1..0bdb4e2ad12 100644 --- a/tools/lli/RemoteMemoryManager.h +++ b/tools/lli/RemoteMemoryManager.h @@ -80,8 +80,7 @@ public: // symbols from Modules it contains. uint64_t getSymbolAddress(const std::string &Name) override { return 0; } - void notifyObjectLoaded(ExecutionEngine *EE, - const object::ObjectFile &Obj) override; + void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj) override; bool finalizeMemory(std::string *ErrMsg) override; diff --git a/tools/llvm-jitlistener/llvm-jitlistener.cpp b/tools/llvm-jitlistener/llvm-jitlistener.cpp index 0f85a85e19c..0bb6e8bc886 100644 --- a/tools/llvm-jitlistener/llvm-jitlistener.cpp +++ b/tools/llvm-jitlistener/llvm-jitlistener.cpp @@ -19,10 +19,10 @@ #include "llvm/ExecutionEngine/JITEventListener.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/ExecutionEngine/MCJIT.h" +#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/IR/Module.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/Host.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index c38e42307dd..87d381e994f 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -13,6 +13,8 @@ #include "llvm/ADT/StringMap.h" #include "llvm/DebugInfo/DIContext.h" +#include "llvm/ExecutionEngine/ObjectBuffer.h" +#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/ExecutionEngine/RuntimeDyldChecker.h" #include "llvm/MC/MCAsmInfo.h" @@ -205,32 +207,23 @@ static int printLineInfoForInput() { if (std::error_code EC = InputBuffer.getError()) return Error("unable to read input: '" + EC.message() + "'"); - ErrorOr> MaybeObj( - ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); - - if (std::error_code EC = MaybeObj.getError()) - return Error("unable to create object file: '" + EC.message() + "'"); - - ObjectFile &Obj = **MaybeObj; - + std::unique_ptr LoadedObject; // Load the object file - std::unique_ptr LoadedObjInfo = - Dyld.loadObject(Obj); - - if (Dyld.hasError()) + LoadedObject = Dyld.loadObject( + llvm::make_unique(std::move(*InputBuffer))); + if (!LoadedObject) { return Error(Dyld.getErrorString()); + } // Resolve all the relocations we can. Dyld.resolveRelocations(); - OwningBinary DebugObj = LoadedObjInfo->getObjectForDebug(Obj); - std::unique_ptr Context( - DIContext::getDWARFContext(*DebugObj.getBinary())); + DIContext::getDWARFContext(*LoadedObject->getObjectFile())); // Use symbol info to iterate functions in the object. - for (object::symbol_iterator I = DebugObj.getBinary()->symbol_begin(), - E = DebugObj.getBinary()->symbol_end(); + for (object::symbol_iterator I = LoadedObject->begin_symbols(), + E = LoadedObject->end_symbols(); I != E; ++I) { object::SymbolRef::Type SymType; if (I->getType(SymType)) continue; @@ -275,17 +268,11 @@ static int executeInput() { MemoryBuffer::getFileOrSTDIN(InputFileList[i]); if (std::error_code EC = InputBuffer.getError()) return Error("unable to read input: '" + EC.message() + "'"); - ErrorOr> MaybeObj( - ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); - - if (std::error_code EC = MaybeObj.getError()) - return Error("unable to create object file: '" + EC.message() + "'"); - - ObjectFile &Obj = **MaybeObj; - + std::unique_ptr LoadedObject; // Load the object file - Dyld.loadObject(Obj); - if (Dyld.hasError()) { + LoadedObject = Dyld.loadObject( + llvm::make_unique(std::move(*InputBuffer))); + if (!LoadedObject) { return Error(Dyld.getErrorString()); } } @@ -525,21 +512,14 @@ static int linkAndVerify() { // Load the input memory buffer. ErrorOr> InputBuffer = MemoryBuffer::getFileOrSTDIN(InputFileList[i]); - if (std::error_code EC = InputBuffer.getError()) return Error("unable to read input: '" + EC.message() + "'"); - ErrorOr> MaybeObj( - ObjectFile::createObjectFile((*InputBuffer)->getMemBufferRef())); - - if (std::error_code EC = MaybeObj.getError()) - return Error("unable to create object file: '" + EC.message() + "'"); - - ObjectFile &Obj = **MaybeObj; - + std::unique_ptr LoadedObject; // Load the object file - Dyld.loadObject(Obj); - if (Dyld.hasError()) { + LoadedObject = Dyld.loadObject( + llvm::make_unique(std::move(*InputBuffer))); + if (!LoadedObject) { return Error(Dyld.getErrorString()); } } -- 2.34.1