diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index e3bb2e8b6e805..977dba0555dac 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -707,22 +707,6 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec, bool isAArch64Auth = ctx.arg.emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64; - 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 - // the symbol. When we have a RELATIVE relocation though, we no longer have - // a reference to the symbol. Because of this, when we have an addend that - // puts the result of the RELATIVE relocation out-of-bounds of the symbol - // (e.g. the addend is outside of [0, sym.getSize()]), the AArch64 MemtagABI - // says we should store the offset to the start of the symbol in the target - // field. This is described in further detail in: - // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#841extended-semantics-of-r_aarch64_relative - if (addend < 0 || static_cast(addend) >= sym.getSize()) - isec.addReloc({expr, type, offsetInSec, addend, &sym}); - return; - } - // Add a relative relocation. If relrDyn section is enabled, and the // relocation offset is guaranteed to be even, add the relocation to // the relrDyn section, otherwise add it to the relaDyn section. @@ -735,6 +719,8 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec, RelrBaseSection *relrDyn = part.relrDyn.get(); if (isAArch64Auth) relrDyn = part.relrAuthDyn.get(); + else if (sym.isTagged()) + relrDyn = nullptr; if (relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0) { relrDyn->addRelativeReloc(isec, offsetInSec, sym, addend, type, expr); @@ -745,6 +731,17 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec, relativeType = R_AARCH64_AUTH_RELATIVE; part.relaDyn->addRelativeReloc(relativeType, isec, offsetInSec, sym, addend, type, expr); + // With MTE globals, we always want to derive the address tag by `ldg`-ing + // the symbol. When we have a RELATIVE relocation though, we no longer have + // a reference to the symbol. Because of this, when we have an addend that + // puts the result of the RELATIVE relocation out-of-bounds of the symbol + // (e.g. the addend is outside of [0, sym.getSize()]), the AArch64 MemtagABI + // says we should store the offset to the start of the symbol in the target + // field. This is described in further detail in: + // 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}); } template