llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lld-elf Author: Jessica Clarke (jrtc27) <details> <summary>Changes</summary> The current implementation in addRelativeReloc makes it look like we're writing the symbol's VA + addend to the section, because that's what the given relocation will evaluate to, but we're supposed to be writing the negated original addend (since the relative relocation's addend will be the sum of the symbol's VA and the original addend). This only works because deep down in AArch64::relocate we throw away the computed value and peek back inside the relocation to extract the addend and negate it. Do this properly by having a relocation that evaluates to the right value instead. --- Full diff: https://github.com/llvm/llvm-project/pull/171182.diff 4 Files Affected: - (modified) lld/ELF/Arch/AArch64.cpp (+1-13) - (modified) lld/ELF/InputSection.cpp (+2) - (modified) lld/ELF/Relocations.cpp (+1-1) - (modified) lld/ELF/Relocations.h (+1) ``````````diff 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<int64_t>(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<uint64_t>(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<uint64_t>(addend) >= sym.getSize())) - isec.addReloc({expr, type, offsetInSec, addend, &sym}); + isec.addReloc({R_ADDEND_NEG, type, offsetInSec, addend, &sym}); } template <class PltSection, class GotPltSection> 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, `````````` </details> https://github.com/llvm/llvm-project/pull/171182 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
