diff options
author | Tim Northover <tnorthover@apple.com> | 2014-03-29 10:18:08 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2014-03-29 10:18:08 +0000 |
commit | 7b837d8c75f78fe55c9b348b9ec2281169a48d2a (patch) | |
tree | e8e01e73cf4d0723a13e49e4b5d8a66f896d184f /lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp | |
parent | 69bd9577fc423edea13479eaacf7b1844faa6c6a (diff) | |
download | llvm-7b837d8c75f78fe55c9b348b9ec2281169a48d2a.tar.gz llvm-7b837d8c75f78fe55c9b348b9ec2281169a48d2a.tar.bz2 llvm-7b837d8c75f78fe55c9b348b9ec2281169a48d2a.tar.xz |
ARM64: initial backend import
This adds a second implementation of the AArch64 architecture to LLVM,
accessible in parallel via the "arm64" triple. The plan over the
coming weeks & months is to merge the two into a single backend,
during which time thorough code review should naturally occur.
Everything will be easier with the target in-tree though, hence this
commit.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205090 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp')
-rw-r--r-- | lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index c1fd821123..7eae9c2145 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -167,6 +167,10 @@ void RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section, resolveARMRelocation(LocalAddress, FinalAddress, (uintptr_t)Value, isPCRel, MachoType, Size, Addend); break; + case Triple::arm64: + resolveARM64Relocation(LocalAddress, FinalAddress, (uintptr_t)Value, + isPCRel, MachoType, Size, Addend); + break; } } @@ -293,6 +297,55 @@ bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress, return false; } +bool RuntimeDyldMachO::resolveARM64Relocation(uint8_t *LocalAddress, + uint64_t FinalAddress, + uint64_t Value, bool isPCRel, + unsigned Type, unsigned Size, + int64_t Addend) { + // If the relocation is PC-relative, the value to be encoded is the + // pointer difference. + if (isPCRel) + Value -= FinalAddress; + + switch (Type) { + default: + llvm_unreachable("Invalid relocation type!"); + case MachO::ARM64_RELOC_UNSIGNED: { + // Mask in the target value a byte at a time (we don't have an alignment + // guarantee for the target address, so this is safest). + uint8_t *p = (uint8_t *)LocalAddress; + for (unsigned i = 0; i < Size; ++i) { + *p++ = (uint8_t)Value; + Value >>= 8; + } + break; + } + case MachO::ARM64_RELOC_BRANCH26: { + // Mask the value into the target address. We know instructions are + // 32-bit aligned, so we can do it all at once. + uint32_t *p = (uint32_t *)LocalAddress; + // The low two bits of the value are not encoded. + Value >>= 2; + // Mask the value to 26 bits. + Value &= 0x3ffffff; + // Insert the value into the instruction. + *p = (*p & ~0x3ffffff) | Value; + break; + } + case MachO::ARM64_RELOC_SUBTRACTOR: + case MachO::ARM64_RELOC_PAGE21: + case MachO::ARM64_RELOC_PAGEOFF12: + case MachO::ARM64_RELOC_GOT_LOAD_PAGE21: + case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: + case MachO::ARM64_RELOC_POINTER_TO_GOT: + case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21: + case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12: + case MachO::ARM64_RELOC_ADDEND: + return Error("Relocation type not implemented yet!"); + } + return false; +} + relocation_iterator RuntimeDyldMachO::processRelocationRef( unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, |