diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index ce7ed5a413beb..e3bb2e8b6e805 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -704,8 +704,10 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec, uint64_t offsetInSec, Symbol &sym, int64_t addend, RelExpr expr, RelType type) { Partition &part = isec.getPartition(ctx); + bool isAArch64Auth = + ctx.arg.emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64; - if (sym.isTagged()) { + if (sym.isTagged() && !isAArch64Auth) { part.relaDyn->addRelativeReloc(ctx.target->relativeRel, isec, offsetInSec, sym, addend, type, expr); // With MTE globals, we always want to derive the address tag by `ldg`-ing @@ -727,13 +729,22 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec, // relrDyn sections don't support odd offsets. Also, relrDyn sections // don't store the addend values, so we must write it to the relocated // address. - if (part.relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0) { - part.relrDyn->addRelativeReloc(isec, offsetInSec, sym, addend, type, - expr); + // + // When symbol values are determined in finalizeAddressDependentContent, + // some .relr.auth.dyn relocations may be moved to .rela.dyn. + RelrBaseSection *relrDyn = part.relrDyn.get(); + if (isAArch64Auth) + relrDyn = part.relrAuthDyn.get(); + if (relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0) { + relrDyn->addRelativeReloc(isec, offsetInSec, sym, addend, type, + expr); return; } - part.relaDyn->addRelativeReloc(ctx.target->relativeRel, isec, - offsetInSec, sym, addend, type, expr); + RelType relativeType = ctx.target->relativeRel; + if (isAArch64Auth) + relativeType = R_AARCH64_AUTH_RELATIVE; + part.relaDyn->addRelativeReloc(relativeType, isec, offsetInSec, sym, + addend, type, expr); } template @@ -992,7 +1003,9 @@ void RelocScan::process(RelExpr expr, RelType type, uint64_t offset, if (canWrite) { RelType rel = ctx.target->getDynRel(type); if (oneof(expr) || - (rel == ctx.target->symbolicRel && !sym.isPreemptible)) { + ((rel == ctx.target->symbolicRel || + (ctx.arg.emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) && + !sym.isPreemptible)) { addRelativeReloc(ctx, *sec, offset, sym, addend, expr, type); return; } @@ -1001,23 +1014,6 @@ void RelocScan::process(RelExpr expr, RelType type, uint64_t offset, rel = ctx.target->relativeRel; std::lock_guard lock(ctx.relocMutex); Partition &part = sec->getPartition(ctx); - // For a preemptible symbol, we can't use a relative relocation. For an - // undefined symbol, we can't compute offset at link-time and use a - // relative relocation. Use a symbolic relocation instead. - if (ctx.arg.emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64 && - !sym.isPreemptible) { - if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0) { - // When symbol values are determined in - // finalizeAddressDependentContent, some .relr.auth.dyn relocations - // may be moved to .rela.dyn. - part.relrAuthDyn->addRelativeReloc(*sec, offset, sym, addend, type, - expr); - } else { - part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset, false, - sym, addend, R_ABS}); - } - return; - } if (LLVM_UNLIKELY(type == ctx.target->iRelSymbolicRel)) { if (sym.isPreemptible) { auto diag = Err(ctx);