diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index 95b06bffa8d0b..111292be182c6 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -55,12 +55,16 @@ class AArch64 : public TargetInfo { void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const; void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, uint64_t val) const; void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const; - void initRelaxer(ArrayRef relocs) const; +}; + +struct AArch64Relaxer { + bool safeToRelaxAdrpLdr = false; + + AArch64Relaxer(ArrayRef relocs); bool tryRelaxAdrpAdd(const Relocation &adrpRel, const Relocation &addRel, uint64_t secAddr, uint8_t *buf) const; bool tryRelaxAdrpLdr(const Relocation &adrpRel, const Relocation &ldrRel, uint64_t secAddr, uint8_t *buf) const; - mutable bool safeToRelaxAdrpLdr = false; }; } // namespace @@ -594,7 +598,7 @@ void AArch64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, llvm_unreachable("invalid relocation for TLS IE to LE relaxation"); } -void AArch64::initRelaxer(ArrayRef relocs) const { +AArch64Relaxer::AArch64Relaxer(ArrayRef relocs) { if (!config->relax) return; // Check if R_AARCH64_ADR_GOT_PAGE and R_AARCH64_LD64_GOT_LO12_NC @@ -615,9 +619,9 @@ void AArch64::initRelaxer(ArrayRef relocs) const { safeToRelaxAdrpLdr = i == size; } -bool AArch64::tryRelaxAdrpAdd(const Relocation &adrpRel, - const Relocation &addRel, uint64_t secAddr, - uint8_t *buf) const { +bool AArch64Relaxer::tryRelaxAdrpAdd(const Relocation &adrpRel, + const Relocation &addRel, uint64_t secAddr, + uint8_t *buf) const { // When the address of sym is within the range of ADR then // we may relax // ADRP xn, sym @@ -664,9 +668,9 @@ bool AArch64::tryRelaxAdrpAdd(const Relocation &adrpRel, return true; } -bool AArch64::tryRelaxAdrpLdr(const Relocation &adrpRel, - const Relocation &ldrRel, uint64_t secAddr, - uint8_t *buf) const { +bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, + const Relocation &ldrRel, uint64_t secAddr, + uint8_t *buf) const { if (!safeToRelaxAdrpLdr) return false; @@ -743,7 +747,7 @@ void AArch64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const { uint64_t secAddr = sec.getOutputSection()->addr; if (auto *s = dyn_cast(&sec)) secAddr += s->outSecOff; - initRelaxer(sec.relocations); + AArch64Relaxer relaxer(sec.relocations); for (size_t i = 0, size = sec.relocations.size(); i != size; ++i) { const Relocation &rel = sec.relocations[i]; uint8_t *loc = buf + rel.offset; @@ -753,14 +757,14 @@ void AArch64::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const { switch (rel.expr) { case R_AARCH64_GOT_PAGE_PC: if (i + 1 < size && - tryRelaxAdrpLdr(rel, sec.relocations[i + 1], secAddr, buf)) { + relaxer.tryRelaxAdrpLdr(rel, sec.relocations[i + 1], secAddr, buf)) { ++i; continue; } break; case R_AARCH64_PAGE_PC: if (i + 1 < size && - tryRelaxAdrpAdd(rel, sec.relocations[i + 1], secAddr, buf)) { + relaxer.tryRelaxAdrpAdd(rel, sec.relocations[i + 1], secAddr, buf)) { ++i; continue; }