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:
parent
22e27a0d1d
commit
384fbc5405
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user