9 #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOAARCH64_H 10 #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOAARCH64_H 12 #include "../RuntimeDyldMachO.h" 15 #define DEBUG_TYPE "dyld" 36 uint8_t *LocalAddress =
Section.getAddressWithOffset(RE.
Offset);
37 unsigned NumBytes = 1 << RE.
Size;
45 ErrStream <<
"Unsupported relocation type: " 48 return make_error<StringError>(
std::move(ErrMsg),
53 if (NumBytes != 4 && NumBytes != 8) {
57 ErrStream <<
"Invalid relocation size for relocation " 60 return make_error<StringError>(
std::move(ErrMsg),
70 assert(NumBytes == 4 &&
"Invalid relocation size.");
71 assert((((uintptr_t)LocalAddress & 0x3) == 0) &&
72 "Instruction address is not aligned to 4 bytes.");
83 Addend = *reinterpret_cast<support::ulittle32_t *>(LocalAddress);
85 Addend = *reinterpret_cast<support::ulittle64_t *>(LocalAddress);
89 auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
90 assert(((*p & 0xFC000000) == 0x14000000 ||
91 (*p & 0xFC000000) == 0x94000000) &&
92 "Expected branch instruction.");
97 Addend = (*p & 0x03FFFFFF) << 2;
104 auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
105 assert((*p & 0x9F000000) == 0x90000000 &&
"Expected adrp instruction.");
110 Addend = ((*p & 0x60000000) >> 29) | ((*p & 0x01FFFFE0) >> 3) << 12;
117 auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
119 assert((*p & 0x3B000000) == 0x39000000 &&
120 "Only expected load / store instructions.");
126 auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
127 assert((((*p & 0x3B000000) == 0x39000000) ||
128 ((*p & 0x11C00000) == 0x11000000) ) &&
129 "Expected load / store or add/sub instruction.");
132 Addend = (*p & 0x003FFC00) >> 10;
136 int ImplicitShift = 0;
137 if ((*p & 0x3B000000) == 0x39000000) {
139 ImplicitShift = ((*p >> 30) & 0x3);
140 if (ImplicitShift == 0) {
142 if ((*p & 0x04800000) == 0x04800000)
147 Addend <<= ImplicitShift;
163 assert((NumBytes == 4 || NumBytes == 8) &&
"Invalid relocation size.");
170 assert(NumBytes == 4 &&
"Invalid relocation size.");
171 assert((((uintptr_t)LocalAddress & 0x3) == 0) &&
172 "Instruction address is not aligned to 4 bytes.");
183 *reinterpret_cast<support::ulittle32_t *>(LocalAddress) = Addend;
185 *reinterpret_cast<support::ulittle64_t *>(LocalAddress) = Addend;
188 auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
190 assert(((*p & 0xFC000000) == 0x14000000 ||
191 (*p & 0xFC000000) == 0x94000000) &&
192 "Expected branch instruction.");
195 assert((Addend & 0x3) == 0 &&
"Branch target is not aligned");
196 assert(isInt<28>(Addend) &&
"Branch target is out of range.");
199 *p = (*p & 0xFC000000) | ((
uint32_t)(Addend >> 2) & 0x03FFFFFF);
205 auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
206 assert((*p & 0x9F000000) == 0x90000000 &&
"Expected adrp instruction.");
209 assert((Addend & 0xFFF) == 0 &&
"ADRP target is not page aligned.");
210 assert(isInt<33>(Addend) &&
"Invalid page reloc value.");
213 uint32_t ImmLoValue = ((uint64_t)Addend << 17) & 0x60000000;
214 uint32_t ImmHiValue = ((uint64_t)Addend >> 9) & 0x00FFFFE0;
215 *p = (*p & 0x9F00001F) | ImmHiValue | ImmLoValue;
221 auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
222 assert((*p & 0x3B000000) == 0x39000000 &&
223 "Only expected load / store instructions.");
230 auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
231 assert((((*p & 0x3B000000) == 0x39000000) ||
232 ((*p & 0x11C00000) == 0x11000000) ) &&
233 "Expected load / store or add/sub instruction.");
237 int ImplicitShift = 0;
238 if ((*p & 0x3B000000) == 0x39000000) {
240 ImplicitShift = ((*p >> 30) & 0x3);
241 switch (ImplicitShift) {
244 if ((*p & 0x04800000) == 0x04800000) {
246 assert(((Addend & 0xF) == 0) &&
247 "128-bit LDR/STR not 16-byte aligned.");
251 assert(((Addend & 0x1) == 0) &&
"16-bit LDR/STR not 2-byte aligned.");
254 assert(((Addend & 0x3) == 0) &&
"32-bit LDR/STR not 4-byte aligned.");
257 assert(((Addend & 0x7) == 0) &&
"64-bit LDR/STR not 8-byte aligned.");
262 Addend >>= ImplicitShift;
263 assert(isUInt<12>(Addend) &&
"Addend cannot be encoded.");
266 *p = (*p & 0xFFC003FF) | ((
uint32_t)(Addend << 10) & 0x003FFC00);
278 static_cast<const MachOObjectFile &>(BaseObjT);
283 return make_error<RuntimeDyldError>(
"Scattered relocations not supported " 284 "for MachO AArch64");
290 int64_t ExplicitAddend = 0;
303 return processSubtractRelocation(SectionID, RelI, Obj, ObjSectionToID);
311 return make_error<StringError>(
"ARM64_RELOC_POINTER_TO_GOT supports " 312 "32-bit pc-rel or 64-bit absolute only",
319 return Addend.takeError();
321 assert((ExplicitAddend == 0 || RE.
Addend == 0) &&
"Relocation has "\
322 "ARM64_RELOC_ADDEND and embedded addend in the instruction.");
324 RE.
Addend = ExplicitAddend;
330 return ValueOrErr.takeError();
336 }
else if (!IsExtern && RE.
IsPCRel)
344 processGOTRelocation(RE,
Value, Stubs);
346 if (
Value.SymbolName)
359 uint8_t *LocalAddress =
Section.getAddressWithOffset(RE.
Offset);
361 static_cast<MachO::RelocationInfoType>(RE.
RelType);
367 assert(!RE.
IsPCRel &&
"PCRel and ARM64_RELOC_UNSIGNED not supported");
379 "ARM64_RELOC_POINTER_TO_GOT only supports 32-bit pc-rel or 64-bit " 390 assert(RE.
IsPCRel &&
"not PCRel and ARM64_RELOC_BRANCH26 not supported");
392 uint64_t FinalAddress =
Section.getLoadAddressWithOffset(RE.
Offset);
393 int64_t PCRelVal =
Value - FinalAddress + RE.
Addend;
399 assert(RE.
IsPCRel &&
"not PCRel and ARM64_RELOC_PAGE21 not supported");
401 uint64_t FinalAddress =
Section.getLoadAddressWithOffset(RE.
Offset);
403 ((
Value + RE.
Addend) & (-4096)) - (FinalAddress & (-4096));
409 assert(!RE.
IsPCRel &&
"PCRel and ARM64_RELOC_PAGEOFF21 not supported");
421 "Unexpected SUBTRACTOR relocation value.");
432 "processRelocationRef!");
448 StubMap::const_iterator i = Stubs.find(
Value);
450 if (i != Stubs.end())
451 Offset = static_cast<int64_t>(i->second);
455 uintptr_t BaseAddress = uintptr_t(
Section.getAddress());
457 uintptr_t StubAddress =
458 (BaseAddress +
Section.getStubOffset() + StubAlignment - 1) &
460 unsigned StubOffset = StubAddress - BaseAddress;
461 Stubs[
Value] = StubOffset;
463 "GOT entry not aligned");
467 if (
Value.SymbolName)
472 Offset = static_cast<int64_t>(StubOffset);
484 static_cast<const MachOObjectFile&>(BaseObjT);
489 uint64_t
Offset = RelI->getOffset();
490 uint8_t *LocalAddress =
Sections[SectionID].getAddressWithOffset(
Offset);
491 unsigned NumBytes = 1 <<
Size;
494 if (!SubtrahendNameOrErr)
497 unsigned SectionBID = SubtrahendI->second.getSectionID();
498 uint64_t SectionBOffset = SubtrahendI->second.getOffset();
504 if (!MinuendNameOrErr)
507 unsigned SectionAID = MinuendI->second.getSectionID();
508 uint64_t SectionAOffset = MinuendI->second.getOffset();
511 SectionAID, SectionAOffset, SectionBID, SectionBOffset,
519 static const char *getRelocName(
uint32_t RelocType) {
533 return "Unrecognized arm64 addend";
RelocationEntry - used to represent relocations internally in the dynamic linker.
This class represents lattice values for constants.
unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const
uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const
Endian-aware read Read the least significant Size bytes from Src.
Expected< relocation_iterator > processRelocationRef(unsigned SectionID, relocation_iterator RelI, const ObjectFile &BaseObjT, ObjSectionToIDMap &ObjSectionToID, StubMap &Stubs) override
Parses one or more object file relocations (some object files use relocation pairs) and stores it to ...
bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const
iterator find(StringRef Key)
void dumpRelocationToResolve(const RelocationEntry &RE, uint64_t Value) const
Dump information about the relocation entry (RE) and resolved value.
This class is the base class for all object file types.
Error takeError()
Take ownership of the stored error.
void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const
Endian-aware write.
bool IsPCRel
True if this is a PCRel relocation (MachO specific).
unsigned SectionID
SectionID - the section this relocation points to.
std::map< RelocationValueRef, uintptr_t > StubMap
Tagged union holding either a T or a Error.
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override
A object file specific relocation resolver.
unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const
RuntimeDyldMachOTarget - Templated base class for generic MachO linker algorithms and data structures...
Expected< RelocationValueRef > getRelocationValueRef(const ObjectFile &BaseTObj, const relocation_iterator &RI, const RelocationEntry &RE, ObjSectionToIDMap &ObjSectionToID)
Construct a RelocationValueRef representing the relocation target.
void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)
Error finalizeSection(const ObjectFile &Obj, unsigned SectionID, const SectionRef &Section)
unsigned getMaxStubSize() const override
RelocationEntry getRelocationEntry(unsigned SectionID, const ObjectFile &BaseTObj, const relocation_iterator &RI) const
Given a relocation_iterator for a non-scattered relocation, construct a RelocationEntry and fill in t...
void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Symbol resolution interface.
void encodeAddend(uint8_t *LocalAddress, unsigned NumBytes, MachO::RelocationInfoType RelType, int64_t Addend) const
Extract the addend encoded in the instruction.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isRelocationScattered(const MachO::any_relocation_info &RE) const
static ErrorSuccess success()
Create a success value.
RuntimeDyldMachOAArch64(RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver)
int64_t Addend
Addend - the relocation addend encoded in the instruction itself.
uint32_t RelType
RelType - relocation type.
Expected< int64_t > decodeAddend(const RelocationEntry &RE) const
Extract the addend encoded in the instruction / memory location.
unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const
uint64_t Offset
Offset - offset into the section.
std::map< SectionRef, unsigned > ObjSectionToIDMap
unsigned getPlainRelocationSymbolNum(const MachO::any_relocation_info &RE) const
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
SectionEntry - represents a section emitted into memory by the dynamic linker.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getStubAlignment() override
A raw_ostream that writes to an std::string.
LLVM Value Representation.
RTDyldSymbolTable GlobalSymbolTable
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Lightweight error class with error context and mandatory checking.
unsigned Size
The size of this relocation (MachO specific).
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
void makeValueAddendPCRel(RelocationValueRef &Value, const relocation_iterator &RI, unsigned OffsetToNextPC)
Make the RelocationValueRef addend PC-relative.
This is a value type class that represents a single section in the list of sections in the object fil...
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...