diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
| commit | 145449b1e420787bb99721a429341fa6be3adfb6 (patch) | |
| tree | 1d56ae694a6de602e348dd80165cf881a36600ed /lld/MachO/Arch/ARM64Common.cpp | |
| parent | ecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff) | |
Diffstat (limited to 'lld/MachO/Arch/ARM64Common.cpp')
| -rw-r--r-- | lld/MachO/Arch/ARM64Common.cpp | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/lld/MachO/Arch/ARM64Common.cpp b/lld/MachO/Arch/ARM64Common.cpp index 67e7292fd6fd..f55258ce8ec9 100644 --- a/lld/MachO/Arch/ARM64Common.cpp +++ b/lld/MachO/Arch/ARM64Common.cpp @@ -38,56 +38,57 @@ int64_t ARM64Common::getEmbeddedAddend(MemoryBufferRef mb, uint64_t offset, } } +static void writeValue(uint8_t *loc, const Reloc &r, uint64_t value) { + switch (r.length) { + case 2: + checkInt(loc, r, value, 32); + write32le(loc, value); + break; + case 3: + write64le(loc, value); + break; + default: + llvm_unreachable("invalid r_length"); + } +} + // For instruction relocations (load, store, add), the base // instruction is pre-populated in the text section. A pre-populated // instruction has opcode & register-operand bits set, with immediate // operands zeroed. We read it from text, OR-in the immediate // operands, then write-back the completed instruction. - void ARM64Common::relocateOne(uint8_t *loc, const Reloc &r, uint64_t value, uint64_t pc) const { + auto loc32 = reinterpret_cast<uint32_t *>(loc); uint32_t base = ((r.length == 2) ? read32le(loc) : 0); switch (r.type) { case ARM64_RELOC_BRANCH26: - value = encodeBranch26(r, base, value - pc); + encodeBranch26(loc32, r, base, value - pc); break; case ARM64_RELOC_SUBTRACTOR: case ARM64_RELOC_UNSIGNED: - if (r.length == 2) - checkInt(r, value, 32); + writeValue(loc, r, value); break; case ARM64_RELOC_POINTER_TO_GOT: if (r.pcrel) value -= pc; - checkInt(r, value, 32); + writeValue(loc, r, value); break; case ARM64_RELOC_PAGE21: case ARM64_RELOC_GOT_LOAD_PAGE21: - case ARM64_RELOC_TLVP_LOAD_PAGE21: { + case ARM64_RELOC_TLVP_LOAD_PAGE21: assert(r.pcrel); - value = encodePage21(r, base, pageBits(value) - pageBits(pc)); + encodePage21(loc32, r, base, pageBits(value) - pageBits(pc)); break; - } case ARM64_RELOC_PAGEOFF12: case ARM64_RELOC_GOT_LOAD_PAGEOFF12: case ARM64_RELOC_TLVP_LOAD_PAGEOFF12: assert(!r.pcrel); - value = encodePageOff12(base, value); + encodePageOff12(loc32, base, value); break; default: llvm_unreachable("unexpected relocation type"); } - - switch (r.length) { - case 2: - write32le(loc, value); - break; - case 3: - write64le(loc, value); - break; - default: - llvm_unreachable("invalid r_length"); - } } void ARM64Common::relaxGotLoad(uint8_t *loc, uint8_t type) const { |
