1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[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.

llvm-svn: 216801
This commit is contained in:
Lang Hames 2014-08-29 23:17:47 +00:00
parent 22e27a0d1d
commit 384fbc5405
8 changed files with 46 additions and 57 deletions

View File

@ -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<uint8_t*>(&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<uint8_t*>(&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,

View File

@ -703,22 +703,8 @@ uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
unsigned Size) const {
uintptr_t PtrSizedAddr = static_cast<uintptr_t>(SrcAddr);
assert(PtrSizedAddr == SrcAddr && "Linker memory pointer out-of-range.");
uint64_t Result = 0;
uint8_t *Src = reinterpret_cast<uint8_t*>(PtrSizedAddr);
uint8_t *Dst = reinterpret_cast<uint8_t*>(&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<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(

View File

@ -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.

View File

@ -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<uint8_t*>(&Addend);
uint8_t *Src = Sections[RE.SectionID].Address + RE.Offset;
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++;
}
return Addend;
return static_cast<int64_t>(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<uint8_t*>(&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)

View File

@ -117,10 +117,6 @@ public:
static std::unique_ptr<RuntimeDyldMachO> 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;

View File

@ -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

View File

@ -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:

View File

@ -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: