From 361153e264b07766dd1721e460247df14a802a6a Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Fri, 29 Aug 2014 23:17:47 +0000 Subject: [PATCH] [MCJIT] Move endian-aware read/writes from RuntimeDyldMachO into RuntimeDyldImpl. These are platform independent, and moving them to the base class allows RuntimeDyldChecker to use them too. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216801 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../RuntimeDyld/RuntimeDyld.cpp | 32 +++++++++++++++++ .../RuntimeDyld/RuntimeDyldChecker.cpp | 16 +-------- .../RuntimeDyld/RuntimeDyldImpl.h | 7 ++++ .../RuntimeDyld/RuntimeDyldMachO.cpp | 36 ++----------------- .../RuntimeDyld/RuntimeDyldMachO.h | 4 --- .../RuntimeDyld/Targets/RuntimeDyldMachOARM.h | 2 +- .../Targets/RuntimeDyldMachOI386.h | 4 +-- .../Targets/RuntimeDyldMachOX86_64.h | 2 +- 8 files changed, 46 insertions(+), 57 deletions(-) diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 7693fd5d0e7..537a683cd5f 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -395,6 +395,38 @@ unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj, return StubBufSize; } +uint64_t RuntimeDyldImpl::readBytesUnaligned(uint8_t *Src, + unsigned Size) const { + uint64_t Result = 0; + uint8_t *Dst = reinterpret_cast(&Result); + + if (IsTargetLittleEndian == sys::IsLittleEndianHost) { + if (!sys::IsLittleEndianHost) + Dst += sizeof(Result) - Size; + memcpy(Dst, Src, Size); + } else { + Dst += Size - 1; + for (unsigned i = 0; i < Size; ++i) + *Dst-- = *Src++; + } + + return Result; +} + +void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst, + unsigned Size) const { + uint8_t *Src = reinterpret_cast(&Value); + if (IsTargetLittleEndian == sys::IsLittleEndianHost) { + if (!sys::IsLittleEndianHost) + Src += sizeof(Value) - Size; + memcpy(Dst, Src, Size); + } else { + Src += Size - 1; + for (unsigned i = 0; i < Size; ++i) + *Dst++ = *Src--; + } +} + void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj, const CommonSymbolMap &CommonSymbols, uint64_t TotalSize, diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp index 72aae96e0c6..aa4480226ac 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp @@ -703,22 +703,8 @@ uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr, unsigned Size) const { uintptr_t PtrSizedAddr = static_cast(SrcAddr); assert(PtrSizedAddr == SrcAddr && "Linker memory pointer out-of-range."); - uint64_t Result = 0; uint8_t *Src = reinterpret_cast(PtrSizedAddr); - uint8_t *Dst = reinterpret_cast(&Result); - - // If host and target endianness match use memcpy, otherwise copy in reverse - // order. - if (getRTDyld().IsTargetLittleEndian == sys::IsLittleEndianHost) { - if (!sys::IsLittleEndianHost) - Dst += sizeof(Result) - Size; - memcpy(Dst, Src, Size); - } else { - Dst += Size - 1; - for (unsigned i = 0; i < Size; ++i) - *Dst-- = *Src++; - } - return Result; + return getRTDyld().readBytesUnaligned(Src, Size); } std::pair RuntimeDyldCheckerImpl::getStubAddrFor( diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 379cb4ad868..d2c58eb0a64 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -286,6 +286,13 @@ protected: *(Addr + 7) = Value & 0xFF; } + /// Endian-aware read Read the least significant Size bytes from Src. + uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const; + + /// Endian-aware write. Write the least significant Size bytes from Value to + /// Dst. + void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const; + /// \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. diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index a22689a40d9..c89978411dd 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -28,23 +28,10 @@ using namespace llvm::object; namespace llvm { int64_t RuntimeDyldMachO::memcpyAddend(const RelocationEntry &RE) const { - const SectionEntry &Section = Sections[RE.SectionID]; unsigned NumBytes = 1 << RE.Size; - int64_t Addend = 0; - uint8_t *LocalAddress = Section.Address + RE.Offset; - uint8_t *Dst = reinterpret_cast(&Addend); - - if (IsTargetLittleEndian == sys::IsLittleEndianHost) { - if (!sys::IsLittleEndianHost) - Dst += sizeof(Addend) - NumBytes; - memcpy(Dst, LocalAddress, NumBytes); - } else { - Dst += NumBytes - 1; - for (unsigned i = 0; i < NumBytes; ++i) - *Dst-- = *LocalAddress++; - } + uint8_t *Src = Sections[RE.SectionID].Address + RE.Offset; - return Addend; + return static_cast(readBytesUnaligned(Src, NumBytes)); } RelocationValueRef RuntimeDyldMachO::getRelocationValueRef( @@ -121,25 +108,6 @@ void RuntimeDyldMachO::dumpRelocationToResolve(const RelocationEntry &RE, << " Size: " << (1 << RE.Size) << "\n"; } -bool RuntimeDyldMachO::writeBytesUnaligned(uint8_t *Dst, uint64_t Value, - unsigned Size) { - - uint8_t *Src = reinterpret_cast(&Value); - // If host and target endianness match use memcpy, otherwise copy in reverse - // order. - if (IsTargetLittleEndian == sys::IsLittleEndianHost) { - if (!sys::IsLittleEndianHost) - Src += sizeof(Value) - Size; - memcpy(Dst, Src, Size); - } else { - Src += Size - 1; - for (unsigned i = 0; i < Size; ++i) - *Dst++ = *Src--; - } - - return false; -} - bool RuntimeDyldMachO::isCompatibleFormat(const ObjectBuffer *InputBuffer) const { if (InputBuffer->getBufferSize() < 4) diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index 45954a4918b..c017c2225b4 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -117,10 +117,6 @@ public: static std::unique_ptr create(Triple::ArchType Arch, RTDyldMemoryManager *mm); - /// Write the least significant 'Size' bytes in 'Value' out at the address - /// pointed to by Addr. Check for overflow. - bool writeBytesUnaligned(uint8_t *Dst, uint64_t Value, unsigned Size); - SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; } bool isCompatibleFormat(const ObjectBuffer *Buffer) const override; diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h index c7e650bbfd2..395ffaa5863 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h @@ -98,7 +98,7 @@ public: default: llvm_unreachable("Invalid relocation type!"); case MachO::ARM_RELOC_VANILLA: - writeBytesUnaligned(LocalAddress, Value, 1 << RE.Size); + writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size); break; case MachO::ARM_RELOC_BR24: { // Mask the value into the target address. We know instructions are diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h index 07b6e6388d2..10b19019a74 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h @@ -90,7 +90,7 @@ public: default: llvm_unreachable("Invalid relocation type!"); case MachO::GENERIC_RELOC_VANILLA: - writeBytesUnaligned(LocalAddress, Value + RE.Addend, 1 << RE.Size); + writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size); break; case MachO::GENERIC_RELOC_SECTDIFF: case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: { @@ -99,7 +99,7 @@ public: assert((Value == SectionABase || Value == SectionBBase) && "Unexpected SECTDIFF relocation value."); Value = SectionABase - SectionBBase + RE.Addend; - writeBytesUnaligned(LocalAddress, Value, 1 << RE.Size); + writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size); break; } case MachO::GENERIC_RELOC_PB_LA_PTR: diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h index d4f3ccde05f..425695cca9c 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h @@ -84,7 +84,7 @@ public: case MachO::X86_64_RELOC_SIGNED: case MachO::X86_64_RELOC_UNSIGNED: case MachO::X86_64_RELOC_BRANCH: - writeBytesUnaligned(LocalAddress, Value + RE.Addend, 1 << RE.Size); + writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size); break; case MachO::X86_64_RELOC_GOT_LOAD: case MachO::X86_64_RELOC_GOT: -- 2.34.1