llvm.org GIT mirror llvm / 361153e
[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 Lang Hames 6 years ago
8 changed file(s) with 47 addition(s) and 58 deletion(s). Raw diff Collapse all Expand all
392392 if (StubAlignment > EndAlignment)
393393 StubBufSize += StubAlignment - EndAlignment;
394394 return StubBufSize;
395 }
396
397 uint64_t RuntimeDyldImpl::readBytesUnaligned(uint8_t *Src,
398 unsigned Size) const {
399 uint64_t Result = 0;
400 uint8_t *Dst = reinterpret_cast(&Result);
401
402 if (IsTargetLittleEndian == sys::IsLittleEndianHost) {
403 if (!sys::IsLittleEndianHost)
404 Dst += sizeof(Result) - Size;
405 memcpy(Dst, Src, Size);
406 } else {
407 Dst += Size - 1;
408 for (unsigned i = 0; i < Size; ++i)
409 *Dst-- = *Src++;
410 }
411
412 return Result;
413 }
414
415 void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst,
416 unsigned Size) const {
417 uint8_t *Src = reinterpret_cast(&Value);
418 if (IsTargetLittleEndian == sys::IsLittleEndianHost) {
419 if (!sys::IsLittleEndianHost)
420 Src += sizeof(Value) - Size;
421 memcpy(Dst, Src, Size);
422 } else {
423 Src += Size - 1;
424 for (unsigned i = 0; i < Size; ++i)
425 *Dst++ = *Src--;
426 }
395427 }
396428
397429 void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
702702 unsigned Size) const {
703703 uintptr_t PtrSizedAddr = static_cast(SrcAddr);
704704 assert(PtrSizedAddr == SrcAddr && "Linker memory pointer out-of-range.");
705 uint64_t Result = 0;
706705 uint8_t *Src = reinterpret_cast(PtrSizedAddr);
707 uint8_t *Dst = reinterpret_cast(&Result);
708
709 // If host and target endianness match use memcpy, otherwise copy in reverse
710 // order.
711 if (getRTDyld().IsTargetLittleEndian == sys::IsLittleEndianHost) {
712 if (!sys::IsLittleEndianHost)
713 Dst += sizeof(Result) - Size;
714 memcpy(Dst, Src, Size);
715 } else {
716 Dst += Size - 1;
717 for (unsigned i = 0; i < Size; ++i)
718 *Dst-- = *Src++;
719 }
720 return Result;
706 return getRTDyld().readBytesUnaligned(Src, Size);
721707 }
722708
723709 std::pair RuntimeDyldCheckerImpl::getStubAddrFor(
285285 *(Addr + 7) = Value & 0xFF;
286286 }
287287
288 /// Endian-aware read Read the least significant Size bytes from Src.
289 uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const;
290
291 /// Endian-aware write. Write the least significant Size bytes from Value to
292 /// Dst.
293 void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const;
294
288295 /// \brief Given the common symbols discovered in the object file, emit a
289296 /// new section for them and update the symbol mappings in the object and
290297 /// symbol table.
2727 namespace llvm {
2828
2929 int64_t RuntimeDyldMachO::memcpyAddend(const RelocationEntry &RE) const {
30 const SectionEntry &Section = Sections[RE.SectionID];
3130 unsigned NumBytes = 1 << RE.Size;
32 int64_t Addend = 0;
33 uint8_t *LocalAddress = Section.Address + RE.Offset;
34 uint8_t *Dst = reinterpret_cast(&Addend);
35
36 if (IsTargetLittleEndian == sys::IsLittleEndianHost) {
37 if (!sys::IsLittleEndianHost)
38 Dst += sizeof(Addend) - NumBytes;
39 memcpy(Dst, LocalAddress, NumBytes);
40 } else {
41 Dst += NumBytes - 1;
42 for (unsigned i = 0; i < NumBytes; ++i)
43 *Dst-- = *LocalAddress++;
44 }
45
46 return Addend;
31 uint8_t *Src = Sections[RE.SectionID].Address + RE.Offset;
32
33 return static_cast(readBytesUnaligned(Src, NumBytes));
4734 }
4835
4936 RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(
120107 << " Size: " << (1 << RE.Size) << "\n";
121108 }
122109
123 bool RuntimeDyldMachO::writeBytesUnaligned(uint8_t *Dst, uint64_t Value,
124 unsigned Size) {
125
126 uint8_t *Src = reinterpret_cast(&Value);
127 // If host and target endianness match use memcpy, otherwise copy in reverse
128 // order.
129 if (IsTargetLittleEndian == sys::IsLittleEndianHost) {
130 if (!sys::IsLittleEndianHost)
131 Src += sizeof(Value) - Size;
132 memcpy(Dst, Src, Size);
133 } else {
134 Src += Size - 1;
135 for (unsigned i = 0; i < Size; ++i)
136 *Dst++ = *Src--;
137 }
138
139 return false;
140 }
141
142110 bool
143111 RuntimeDyldMachO::isCompatibleFormat(const ObjectBuffer *InputBuffer) const {
144112 if (InputBuffer->getBufferSize() < 4)
116116 static std::unique_ptr create(Triple::ArchType Arch,
117117 RTDyldMemoryManager *mm);
118118
119 /// Write the least significant 'Size' bytes in 'Value' out at the address
120 /// pointed to by Addr. Check for overflow.
121 bool writeBytesUnaligned(uint8_t *Dst, uint64_t Value, unsigned Size);
122
123119 SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; }
124120
125121 bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
9797 default:
9898 llvm_unreachable("Invalid relocation type!");
9999 case MachO::ARM_RELOC_VANILLA:
100 writeBytesUnaligned(LocalAddress, Value, 1 << RE.Size);
100 writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size);
101101 break;
102102 case MachO::ARM_RELOC_BR24: {
103103 // Mask the value into the target address. We know instructions are
8989 default:
9090 llvm_unreachable("Invalid relocation type!");
9191 case MachO::GENERIC_RELOC_VANILLA:
92 writeBytesUnaligned(LocalAddress, Value + RE.Addend, 1 << RE.Size);
92 writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size);
9393 break;
9494 case MachO::GENERIC_RELOC_SECTDIFF:
9595 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
9898 assert((Value == SectionABase || Value == SectionBBase) &&
9999 "Unexpected SECTDIFF relocation value.");
100100 Value = SectionABase - SectionBBase + RE.Addend;
101 writeBytesUnaligned(LocalAddress, Value, 1 << RE.Size);
101 writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size);
102102 break;
103103 }
104104 case MachO::GENERIC_RELOC_PB_LA_PTR:
8383 case MachO::X86_64_RELOC_SIGNED:
8484 case MachO::X86_64_RELOC_UNSIGNED:
8585 case MachO::X86_64_RELOC_BRANCH:
86 writeBytesUnaligned(LocalAddress, Value + RE.Addend, 1 << RE.Size);
86 writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size);
8787 break;
8888 case MachO::X86_64_RELOC_GOT_LOAD:
8989 case MachO::X86_64_RELOC_GOT: