diff options
author | Lang Hames <lhames@gmail.com> | 2014-01-08 04:09:09 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2014-01-08 04:09:09 +0000 |
commit | 42fdb1f00ffc5d0a0326f11cadaeec1c26691688 (patch) | |
tree | 5294abeb5fb8c95d81ced305ed1a9d5d0ba7849b /lib/ExecutionEngine/RuntimeDyld | |
parent | 0fe78d5669e37cf9c5b613ef56b4e5a2de975271 (diff) | |
download | llvm-42fdb1f00ffc5d0a0326f11cadaeec1c26691688.tar.gz llvm-42fdb1f00ffc5d0a0326f11cadaeec1c26691688.tar.bz2 llvm-42fdb1f00ffc5d0a0326f11cadaeec1c26691688.tar.xz |
Re-apply r196639: Add support for archives and object file caching under MCJIT.
I believe the bot failures on linux systems were due to overestimating the
alignment of object-files within archives, which are only guaranteed to be
two-byte aligned. I have reduced the alignment in
RuntimeDyldELF::createObjectImageFromFile accordingly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198737 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld')
7 files changed, 92 insertions, 3 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h index 28680044a3..7666a869d6 100644 --- a/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h +++ b/lib/ExecutionEngine/RuntimeDyld/ObjectImageCommon.h @@ -20,6 +20,10 @@ namespace llvm { +namespace object { + class ObjectFile; +} + class ObjectImageCommon : public ObjectImage { ObjectImageCommon(); // = delete ObjectImageCommon(const ObjectImageCommon &other); // = delete @@ -42,6 +46,8 @@ public: { ObjFile = object::ObjectFile::createObjectFile(Buffer->getMemBuffer()); } + ObjectImageCommon(object::ObjectFile* Input) + : ObjectImage(NULL), ObjFile(Input) {} virtual ~ObjectImageCommon() { delete ObjFile; } virtual object::symbol_iterator begin_symbols() const diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 14e867d7c1..f99d7d0b27 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -82,12 +82,24 @@ ObjectImage *RuntimeDyldImpl::createObjectImage(ObjectBuffer *InputBuffer) { return new ObjectImageCommon(InputBuffer); } +ObjectImage *RuntimeDyldImpl::createObjectImageFromFile(ObjectFile *InputObject) { + return new ObjectImageCommon(InputObject); +} + +ObjectImage *RuntimeDyldImpl::loadObject(ObjectFile *InputObject) { + return loadObject(createObjectImageFromFile(InputObject)); +} + ObjectImage *RuntimeDyldImpl::loadObject(ObjectBuffer *InputBuffer) { + return loadObject(createObjectImage(InputBuffer)); +} + +ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) { MutexGuard locked(lock); - OwningPtr<ObjectImage> obj(createObjectImage(InputBuffer)); + OwningPtr<ObjectImage> obj(InputObject); if (!obj) - report_fatal_error("Unable to create object image from memory buffer!"); + return NULL; // Save information about our target Arch = (Triple::ArchType)obj->getArch(); @@ -139,7 +151,7 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectBuffer *InputBuffer) { if (si == obj->end_sections()) continue; Check(si->getContents(SectionData)); Check(si->isText(IsCode)); - const uint8_t* SymPtr = (const uint8_t*)InputBuffer->getBufferStart() + + const uint8_t* SymPtr = (const uint8_t*)InputObject->getData().data() + (uintptr_t)FileOffset; uintptr_t SectOffset = (uintptr_t)(SymPtr - (const uint8_t*)SectionData.begin()); @@ -563,6 +575,22 @@ RuntimeDyld::~RuntimeDyld() { delete Dyld; } +ObjectImage *RuntimeDyld::loadObject(ObjectFile *InputObject) { + if (!Dyld) { + if (InputObject->isELF()) + Dyld = new RuntimeDyldELF(MM); + else if (InputObject->isMachO()) + Dyld = new RuntimeDyldMachO(MM); + else + report_fatal_error("Incompatible object format!"); + } else { + if (!Dyld->isCompatibleFile(InputObject)) + report_fatal_error("Incompatible object format!"); + } + + return Dyld->loadObject(InputObject); +} + ObjectImage *RuntimeDyld::loadObject(ObjectBuffer *InputBuffer) { if (!Dyld) { sys::fs::file_magic Type = diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index f2c69fc99c..ec9193120d 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -25,6 +25,8 @@ #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/ELF.h" +#include "llvm/Support/MemoryBuffer.h" + using namespace llvm; using namespace llvm::object; @@ -178,6 +180,39 @@ void RuntimeDyldELF::deregisterEHFrames() { RegisteredEHFrameSections.clear(); } +ObjectImage *RuntimeDyldELF::createObjectImageFromFile(object::ObjectFile *ObjFile) { + if (!ObjFile) + return NULL; + + error_code ec; + MemoryBuffer* Buffer = MemoryBuffer::getMemBuffer(ObjFile->getData(), + "", + false); + + if (ObjFile->getBytesInAddress() == 4 && ObjFile->isLittleEndian()) { + DyldELFObject<ELFType<support::little, 2, false> > *Obj = + new DyldELFObject<ELFType<support::little, 2, false> >(Buffer, ec); + return new ELFObjectImage<ELFType<support::little, 2, false> >(NULL, Obj); + } + else if (ObjFile->getBytesInAddress() == 4 && !ObjFile->isLittleEndian()) { + DyldELFObject<ELFType<support::big, 2, false> > *Obj = + new DyldELFObject<ELFType<support::big, 2, false> >(Buffer, ec); + return new ELFObjectImage<ELFType<support::big, 2, false> >(NULL, Obj); + } + else if (ObjFile->getBytesInAddress() == 8 && !ObjFile->isLittleEndian()) { + DyldELFObject<ELFType<support::big, 2, true> > *Obj = + new DyldELFObject<ELFType<support::big, 2, true> >(Buffer, ec); + return new ELFObjectImage<ELFType<support::big, 2, true> >(NULL, Obj); + } + else if (ObjFile->getBytesInAddress() == 8 && ObjFile->isLittleEndian()) { + DyldELFObject<ELFType<support::little, 2, true> > *Obj = + new DyldELFObject<ELFType<support::little, 2, true> >(Buffer, ec); + return new ELFObjectImage<ELFType<support::little, 2, true> >(NULL, Obj); + } + else + llvm_unreachable("Unexpected ELF format"); +} + ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) { if (Buffer->getBufferSize() < ELF::EI_NIDENT) llvm_unreachable("Unexpected ELF object size"); @@ -1403,4 +1438,9 @@ bool RuntimeDyldELF::isCompatibleFormat(const ObjectBuffer *Buffer) const { 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 3adf82706a..181964faa9 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -140,7 +140,9 @@ public: const SymbolTableMap &Symbols, StubMap &Stubs); virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const; + virtual bool isCompatibleFile(const object::ObjectFile *Buffer) const; virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer); + virtual ObjectImage *createObjectImageFromFile(object::ObjectFile *Obj); virtual void registerEHFrames(); virtual void deregisterEHFrames(); virtual void finalizeLoad(ObjSectionToIDMap &SectionMap); diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 634f6cebe1..56970aebef 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -311,12 +311,18 @@ protected: virtual void updateGOTEntries(StringRef Name, uint64_t Addr) {} virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer); + virtual ObjectImage *createObjectImageFromFile(object::ObjectFile *InputObject); + + // This is the implementation for the two public overloads + ObjectImage *loadObject(ObjectImage *InputObject); + public: RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {} virtual ~RuntimeDyldImpl(); ObjectImage *loadObject(ObjectBuffer *InputBuffer); + ObjectImage *loadObject(object::ObjectFile *InputObject); void *getSymbolAddress(StringRef Name) { // FIXME: Just look up as a function for now. Overly simple of course. @@ -354,6 +360,7 @@ public: StringRef getErrorString() { return ErrorStr; } virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0; + virtual bool isCompatibleFile(const ObjectFile *Obj) const = 0; virtual void registerEHFrames(); diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 66ee50ebe9..d12e7e5e4d 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -455,4 +455,9 @@ bool RuntimeDyldMachO::isCompatibleFormat( return false; } +bool RuntimeDyldMachO::isCompatibleFile( + const object::ObjectFile *Obj) const { + return Obj->isMachO(); +} + } // end namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index 3e0870da02..d42e2972aa 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -94,6 +94,7 @@ public: const SymbolTableMap &Symbols, StubMap &Stubs); virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const; + virtual bool isCompatibleFile(const object::ObjectFile *Obj) const; virtual void registerEHFrames(); virtual void finalizeLoad(ObjSectionToIDMap &SectionMap); }; |