Lines Matching +full:page +full:- +full:offset

1 //===- ARM64.cpp ----------------------------------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
16 #include "mach-o/compact_unwind_encoding.h"
50 // POINTER_TO_GOT: ld64 supports a 4-byte pc-relative form as well as an 8-byte
52 // are weird -- it results in the value of the GOT slot being written, instead
53 // of the address. Let's not support it unless we find a real-world use case.
74 0x90000010, // 00: adrp x16, __la_symbol_ptr@page
85 0x90000011, // 00: adrp x17, _dyld_private@page
87 0xa9bf47f0, // 08: stp x16/x17, [sp, #-16]!
88 0x90000010, // 0c: adrp x16, dyld_stub_binder@page
109 0x90000001, // adrp x1, __objc_selrefs@page
111 0x90000010, // adrp x16, _got@page
120 0x90000001, // adrp x1, __objc_selrefs@page
132 if (config->objcStubsMode == ObjCStubsMode::fast) { in writeObjCMsgSendStub()
133 objcStubSize = target->objcStubsFastSize; in writeObjCMsgSendStub()
134 objcMsgSendAddr = in.got->addr; in writeObjCMsgSendStub()
135 objcMsgSendIndex = objcMsgSend->gotIndex; in writeObjCMsgSendStub()
140 assert(config->objcStubsMode == ObjCStubsMode::small); in writeObjCMsgSendStub()
141 objcStubSize = target->objcStubsSmallSize; in writeObjCMsgSendStub()
143 objcMsgSendAddr = d->getVA(); in writeObjCMsgSendStub()
146 objcMsgSendAddr = in.stubs->addr; in writeObjCMsgSendStub()
147 objcMsgSendIndex = objcMsgSend->stubsIndex; in writeObjCMsgSendStub()
160 0x90000010, // 00: adrp x16, <thunk.ptr>@page
166 thunk->align = 4; in populateThunk()
167 thunk->data = {reinterpret_cast<const uint8_t *>(thunkCode), in populateThunk()
169 thunk->relocs.emplace_back(/*type=*/ARM64_RELOC_PAGEOFF12, in populateThunk()
171 /*offset=*/4, /*addend=*/0, in populateThunk()
173 thunk->relocs.emplace_back(/*type=*/ARM64_RELOC_PAGE21, in populateThunk()
175 /*offset=*/0, /*addend=*/0, in populateThunk()
192 // multiplied by 4 (since all functions are 4-aligned: The branch range in ARM64()
193 // is -4*(2**(26-1))..4*(2**(26-1) - 1). in ARM64()
195 forwardBranchRange = backwardBranchRange - 4; in ARM64()
227 int64_t offset; member
279 ldr.offset = ((insn >> 10) & 0xfff) << ldr.p2Size; in parseLdr()
296 return ldr.p2Size > 1 && isShiftedInt<19, 2>(ldr.offset); in isLiteralLdrEligible()
301 uint32_t imm19 = (ldr.offset / 4 & maskTrailingOnes<uint32_t>(19)) << 5; in writeLiteralLdr()
324 // only if ldr.offset < 4096, even though the offset is divided by the load's in isImmediateLdrEligible()
325 // size in the 12-bit immediate operand. Only the unsigned offset variant is in isImmediateLdrEligible()
329 return ldr.offset >= 0 && (ldr.offset % size) == 0 && in isImmediateLdrEligible()
330 isUInt<12>(ldr.offset >> ldr.p2Size); in isImmediateLdrEligible()
350 uint32_t immBits = ldr.offset >> ldr.p2Size; in writeImmediateLdr()
355 // target is within the +/- 1 MiB range allowed by the adr's 21 bit signed
356 // immediate offset.
358 // adrp xN, _foo@PAGE
360 // ->
374 uint64_t addr1 = isec->getVA() + offset1; in applyAdrpAdd()
376 int64_t delta = referent - addr1; in applyAdrpAdd()
385 // addresses are located on the same 4096 byte page.
387 // adrp xN, _foo@PAGE
388 // adrp xN, _bar@PAGE
389 // ->
390 // adrp xN, _foo@PAGE
402 uint64_t page1 = pageBits(offset1 + isec->getVA()) + adrp1.addend; in applyAdrpAdrp()
403 uint64_t page2 = pageBits(offset2 + isec->getVA()) + adrp2.addend; in applyAdrpAdrp()
411 // load from a PC-relative address if it is 4-byte aligned and within +/- 1 MiB,
412 // as ldr can encode a signed 19-bit offset that gets multiplied by 4.
414 // adrp xN, _foo@PAGE
416 // ->
430 uint64_t addr1 = isec->getVA() + offset1; in applyAdrpLdr()
431 uint64_t addr2 = isec->getVA() + offset2; in applyAdrpLdr()
432 uint64_t referent = pageBits(addr1) + adrp.addend + ldr.offset; in applyAdrpLdr()
433 ldr.offset = referent - addr2; in applyAdrpLdr()
459 // adrp x0, _foo@PAGE
486 uint64_t addr1 = isec->getVA() + offset1; in applyAdrpAddLdr()
487 uint64_t addr3 = isec->getVA() + offset3; in applyAdrpAddLdr()
490 literalLdr.offset += referent - addr3; in applyAdrpAddLdr()
502 int64_t adrOffset = referent - addr1; in applyAdrpAddLdr()
505 // Note: ld64 moves the offset into the adr instruction for AdrpAddLdr, but in applyAdrpAddLdr()
511 // Move the target's page offset into the ldr's immediate offset. in applyAdrpAddLdr()
512 // adrp x0, _foo@PAGE in applyAdrpAddLdr()
517 immediateLdr.offset += add.addend; in applyAdrpAddLdr()
525 // Relaxes a GOT-indirect load.
526 // If the referenced symbol is external and its GOT entry is within +/- 1 MiB,
561 uint64_t addr1 = isec->getVA() + offset1; in applyAdrpLdrGotLdr()
562 uint64_t addr2 = isec->getVA() + offset2; in applyAdrpLdrGotLdr()
563 uint64_t referent = pageBits(addr1) + adrp.addend + ldr2.offset; in applyAdrpLdrGotLdr()
569 literalLdr.offset = referent - addr2; in applyAdrpLdrGotLdr()
594 // All known LOH types as of 2022-09 have 3 or fewer arguments; skip others. in forEachHint()
618 // points to a sequence of ULEB128-encoded numbers. Each entry specifies a
631 addr < sectionAddr + section->getSize()) in applyOptimizationHints()
638 [](uint64_t off, const Section *sec) { return off < sec->addr; })); in applyOptimizationHints()
641 if (sec->subsections.empty()) in applyOptimizationHints()
644 sec->subsections, addr - sec->addr, in applyOptimizationHints()
645 [](uint64_t off, Subsection subsec) { return off < subsec.offset; })); in applyOptimizationHints()
649 if (!isec || isec->shouldOmitFromOutput()) in applyOptimizationHints()
653 sectionAddr = subsec.offset + sec->addr; in applyOptimizationHints()
654 buf = outBuf + section->outSecOff + section->parent->fileOff; in applyOptimizationHints()
658 auto isValidOffset = [&](uint64_t offset) { in applyOptimizationHints() argument
659 if (offset < sectionAddr || offset >= sectionAddr + section->getSize()) { in applyOptimizationHints()
679 applyAdrpAdd(buf, section, args[0] - sectionAddr, in applyOptimizationHints()
680 args[1] - sectionAddr); in applyOptimizationHints()
684 applyAdrpLdr(buf, section, args[0] - sectionAddr, in applyOptimizationHints()
685 args[1] - sectionAddr); in applyOptimizationHints()
689 applyAdrpLdrGot(buf, section, args[0] - sectionAddr, in applyOptimizationHints()
690 args[1] - sectionAddr); in applyOptimizationHints()
694 applyAdrpAddLdr(buf, section, args[0] - sectionAddr, in applyOptimizationHints()
695 args[1] - sectionAddr, args[2] - sectionAddr); in applyOptimizationHints()
699 applyAdrpLdrGotLdr(buf, section, args[0] - sectionAddr, in applyOptimizationHints()
700 args[1] - sectionAddr, args[2] - sectionAddr); in applyOptimizationHints()
716 // adrp x0, _foo@PAGE in applyOptimizationHints()
718 // adrp x0, _bar@PAGE in applyOptimizationHints()
723 // adrp x0, _foo@PAGE in applyOptimizationHints()
741 applyAdrpAdrp(buf, section, args[0] - sectionAddr, args[1] - sectionAddr); in applyOptimizationHints()