diff options
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp')
-rw-r--r-- | lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 89 |
1 files changed, 45 insertions, 44 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index a1c0e4020fc..efefacf632d 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -12,16 +12,19 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "dyld" +#include "RuntimeDyldELF.h" +#include "JITRegistrar.h" +#include "ObjectImageCommon.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/IntervalMap.h" -#include "RuntimeDyldELF.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/ExecutionEngine/ObjectImage.h" +#include "llvm/ExecutionEngine/ObjectBuffer.h" #include "llvm/Support/ELF.h" #include "llvm/ADT/Triple.h" #include "llvm/Object/ELF.h" -#include "JITRegistrar.h" using namespace llvm; using namespace llvm::object; @@ -41,19 +44,12 @@ class DyldELFObject : public ELFObjectFile<target_endianness, is64Bits> { typedef typename ELFDataTypeTypedefHelper< target_endianness, is64Bits>::value_type addr_type; -protected: - // This duplicates the 'Data' member in the 'Binary' base class - // but it is necessary to workaround a bug in gcc 4.2 - MemoryBuffer *InputData; - public: - DyldELFObject(MemoryBuffer *Object, error_code &ec); + DyldELFObject(MemoryBuffer *Wrapper, error_code &ec); void updateSectionAddress(const SectionRef &Sec, uint64_t Addr); void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr); - const MemoryBuffer& getBuffer() const { return *InputData; } - // Methods for type inquiry through isa, cast and dyn_cast static inline bool classof(const Binary *v) { return (isa<ELFObjectFile<target_endianness, is64Bits> >(v) @@ -69,14 +65,15 @@ public: }; template<support::endianness target_endianness, bool is64Bits> -class ELFObjectImage : public ObjectImage { +class ELFObjectImage : public ObjectImageCommon { protected: DyldELFObject<target_endianness, is64Bits> *DyldObj; bool Registered; public: - ELFObjectImage(DyldELFObject<target_endianness, is64Bits> *Obj) - : ObjectImage(Obj), + ELFObjectImage(ObjectBuffer *Input, + DyldELFObject<target_endianness, is64Bits> *Obj) + : ObjectImageCommon(Input, Obj), DyldObj(Obj), Registered(false) {} @@ -99,20 +96,22 @@ class ELFObjectImage : public ObjectImage { virtual void registerWithDebugger() { - JITRegistrar::getGDBRegistrar().registerObject(DyldObj->getBuffer()); + JITRegistrar::getGDBRegistrar().registerObject(*Buffer); Registered = true; } virtual void deregisterWithDebugger() { - JITRegistrar::getGDBRegistrar().deregisterObject(DyldObj->getBuffer()); + 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 +// this MemoryBuffer object but not the underlying memory. template<support::endianness target_endianness, bool is64Bits> -DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Object, +DyldELFObject<target_endianness, is64Bits>::DyldELFObject(MemoryBuffer *Wrapper, error_code &ec) - : ELFObjectFile<target_endianness, is64Bits>(Object, ec), - InputData(Object) { + : ELFObjectFile<target_endianness, is64Bits>(Wrapper, ec) { this->isDyldELFObject = true; } @@ -148,46 +147,39 @@ void DyldELFObject<target_endianness, is64Bits>::updateSymbolAddress( namespace llvm { -ObjectImage *RuntimeDyldELF::createObjectImage( - const MemoryBuffer *ConstInputBuffer) { - MemoryBuffer *InputBuffer = const_cast<MemoryBuffer*>(ConstInputBuffer); - std::pair<unsigned char, unsigned char> Ident = getElfArchType(InputBuffer); +ObjectImage *RuntimeDyldELF::createObjectImage(ObjectBuffer *Buffer) { + if (Buffer->getBufferSize() < ELF::EI_NIDENT) + llvm_unreachable("Unexpected ELF object size"); + std::pair<unsigned char, unsigned char> Ident = std::make_pair( + (uint8_t)Buffer->getBufferStart()[ELF::EI_CLASS], + (uint8_t)Buffer->getBufferStart()[ELF::EI_DATA]); error_code ec; if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) { DyldELFObject<support::little, false> *Obj = - new DyldELFObject<support::little, false>(InputBuffer, ec); - return new ELFObjectImage<support::little, false>(Obj); + new DyldELFObject<support::little, false>(Buffer->getMemBuffer(), ec); + return new ELFObjectImage<support::little, false>(Buffer, Obj); } else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) { DyldELFObject<support::big, false> *Obj = - new DyldELFObject<support::big, false>(InputBuffer, ec); - return new ELFObjectImage<support::big, false>(Obj); + new DyldELFObject<support::big, false>(Buffer->getMemBuffer(), ec); + return new ELFObjectImage<support::big, false>(Buffer, Obj); } else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) { DyldELFObject<support::big, true> *Obj = - new DyldELFObject<support::big, true>(InputBuffer, ec); - return new ELFObjectImage<support::big, true>(Obj); + new DyldELFObject<support::big, true>(Buffer->getMemBuffer(), ec); + return new ELFObjectImage<support::big, true>(Buffer, Obj); } else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) { DyldELFObject<support::little, true> *Obj = - new DyldELFObject<support::little, true>(InputBuffer, ec); - return new ELFObjectImage<support::little, true>(Obj); + new DyldELFObject<support::little, true>(Buffer->getMemBuffer(), ec); + return new ELFObjectImage<support::little, true>(Buffer, Obj); } else llvm_unreachable("Unexpected ELF format"); } -void RuntimeDyldELF::handleObjectLoaded(ObjectImage *Obj) -{ - Obj->registerWithDebugger(); - // Save the loaded object. It will deregister itself when deleted - LoadedObject = Obj; -} - RuntimeDyldELF::~RuntimeDyldELF() { - if (LoadedObject) - delete LoadedObject; } void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress, @@ -272,14 +264,19 @@ void RuntimeDyldELF::resolveARMRelocation(uint8_t *LocalAddress, default: llvm_unreachable("Not implemented relocation type!"); - // Just write 32bit value to relocation address + // Write a 32bit value to relocation address, taking into account the + // implicit addend encoded in the target. case ELF::R_ARM_ABS32 : - *TargetPtr = Value; + *TargetPtr += Value; break; // Write first 16 bit of 32 bit value to the mov instruction. // Last 4 bit should be shifted. case ELF::R_ARM_MOVW_ABS_NC : + // We are not expecting any other addend in the relocation address. + // Using 0x000F0FFF because MOVW has its 16 bit immediate split into 2 + // non-contiguous fields. + assert((*TargetPtr & 0x000F0FFF) == 0); Value = Value & 0xFFFF; *TargetPtr |= Value & 0xFFF; *TargetPtr |= ((Value >> 12) & 0xF) << 16; @@ -288,6 +285,9 @@ void RuntimeDyldELF::resolveARMRelocation(uint8_t *LocalAddress, // Write last 16 bit of 32 bit value to the mov instruction. // Last 4 bit should be shifted. case ELF::R_ARM_MOVT_ABS : + // We are not expecting any other addend in the relocation address. + // Use 0x000F0FFF for the same reason as R_ARM_MOVW_ABS_NC. + assert((*TargetPtr & 0x000F0FFF) == 0); Value = (Value >> 16) & 0xFFFF; *TargetPtr |= Value & 0xFFF; *TargetPtr |= ((Value >> 12) & 0xF) << 16; @@ -522,8 +522,9 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel, } } -bool RuntimeDyldELF::isCompatibleFormat(const MemoryBuffer *InputBuffer) const { - StringRef Magic = InputBuffer->getBuffer().slice(0, ELF::EI_NIDENT); - return (memcmp(Magic.data(), ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; +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; } } // namespace llvm |