diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index 4613539342f57..f68403b69419f 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -527,19 +527,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel, write32(ctx, loc, val); break; case R_AARCH64_ABS64: - // AArch64 relocations to tagged symbols have extended semantics, as - // described here: - // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#841extended-semantics-of-r_aarch64_relative. - // tl;dr: encode the symbol's special addend in the place, which is an - // offset to the point where the logical tag is derived from. Quick hack, if - // the addend is within the symbol's bounds, no need to encode the tag - // derivation offset. - if (rel.sym && rel.sym->isTagged() && - (rel.addend < 0 || - rel.addend >= static_cast(rel.sym->getSize()))) - write64(ctx, loc, -rel.addend); - else - write64(ctx, loc, val); + write64(ctx, loc, val); break; case R_AARCH64_PREL64: write64(ctx, loc, val); diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index ff7ef2dce5c79..ca8a9c0d27f29 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -784,6 +784,8 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r, return r.sym->getVA(ctx, a); case R_ADDEND: return a; + case R_ADDEND_NEG: + return -static_cast(a); case R_RELAX_HINT: return 0; case RE_ARM_SBREL: diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 977dba0555dac..028e4a6526713 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -741,7 +741,7 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec, // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#841extended-semantics-of-r_aarch64_relative if (sym.isTagged() && !isAArch64Auth && (addend < 0 || static_cast(addend) >= sym.getSize())) - isec.addReloc({expr, type, offsetInSec, addend, &sym}); + isec.addReloc({R_ADDEND_NEG, type, offsetInSec, addend, &sym}); } template diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h index 86ca298cd7a56..4cb09f329953a 100644 --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -42,6 +42,7 @@ using JumpModType = uint32_t; enum RelExpr { R_ABS, R_ADDEND, + R_ADDEND_NEG, R_DTPREL, R_GOT, R_GOT_OFF,