@@ -704,40 +704,44 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec,
704704 uint64_t offsetInSec, Symbol &sym, int64_t addend,
705705 RelExpr expr, RelType type) {
706706 Partition &part = isec.getPartition (ctx);
707-
708- if (sym.isTagged ()) {
709- part.relaDyn ->addRelativeReloc <shard>(ctx.target ->relativeRel , isec,
710- offsetInSec, sym, addend, type, expr);
711- // With MTE globals, we always want to derive the address tag by `ldg`-ing
712- // the symbol. When we have a RELATIVE relocation though, we no longer have
713- // a reference to the symbol. Because of this, when we have an addend that
714- // puts the result of the RELATIVE relocation out-of-bounds of the symbol
715- // (e.g. the addend is outside of [0, sym.getSize()]), the AArch64 MemtagABI
716- // says we should store the offset to the start of the symbol in the target
717- // field. This is described in further detail in:
718- // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#841extended-semantics-of-r_aarch64_relative
719- if (addend < 0 || static_cast <uint64_t >(addend) >= sym.getSize ())
720- isec.relocations .push_back ({expr, type, offsetInSec, addend, &sym});
721- return ;
722- }
707+ bool isAArch64Auth =
708+ ctx.arg .emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64;
723709
724710 // Add a relative relocation. If relrDyn section is enabled, and the
725711 // relocation offset is guaranteed to be even, add the relocation to
726712 // the relrDyn section, otherwise add it to the relaDyn section.
727713 // relrDyn sections don't support odd offsets. Also, relrDyn sections
728714 // don't store the addend values, so we must write it to the relocated
729715 // address.
730- if (part.relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0 ) {
731- isec.addReloc ({expr, type, offsetInSec, addend, &sym});
732- if (shard)
733- part.relrDyn ->relocsVec [parallel::getThreadIndex ()].push_back (
734- {&isec, isec.relocs ().size () - 1 });
735- else
736- part.relrDyn ->relocs .push_back ({&isec, isec.relocs ().size () - 1 });
716+ //
717+ // When symbol values are determined in finalizeAddressDependentContent,
718+ // some .relr.auth.dyn relocations may be moved to .rela.dyn.
719+ RelrBaseSection *relrDyn = part.relrDyn .get ();
720+ if (isAArch64Auth)
721+ relrDyn = part.relrAuthDyn .get ();
722+ else if (sym.isTagged ())
723+ relrDyn = nullptr ;
724+ if (relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0 ) {
725+ relrDyn->addRelativeReloc <shard>(isec, offsetInSec, sym, addend, type,
726+ expr);
737727 return ;
738728 }
739- part.relaDyn ->addRelativeReloc <shard>(ctx.target ->relativeRel , isec,
740- offsetInSec, sym, addend, type, expr);
729+ RelType relativeType = ctx.target ->relativeRel ;
730+ if (isAArch64Auth)
731+ relativeType = R_AARCH64_AUTH_RELATIVE;
732+ part.relaDyn ->addRelativeReloc <shard>(relativeType, isec, offsetInSec, sym,
733+ addend, type, expr);
734+ // With MTE globals, we always want to derive the address tag by `ldg`-ing
735+ // the symbol. When we have a RELATIVE relocation though, we no longer have
736+ // a reference to the symbol. Because of this, when we have an addend that
737+ // puts the result of the RELATIVE relocation out-of-bounds of the symbol
738+ // (e.g. the addend is outside of [0, sym.getSize()]), the AArch64 MemtagABI
739+ // says we should store the offset to the start of the symbol in the target
740+ // field. This is described in further detail in:
741+ // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#841extended-semantics-of-r_aarch64_relative
742+ if (sym.isTagged () && !isAArch64Auth &&
743+ (addend < 0 || static_cast <uint64_t >(addend) >= sym.getSize ()))
744+ isec.addReloc ({R_ADDEND_NEG, type, offsetInSec, addend, &sym});
741745}
742746
743747template <class PltSection , class GotPltSection >
@@ -996,7 +1000,9 @@ void RelocScan::process(RelExpr expr, RelType type, uint64_t offset,
9961000 if (canWrite) {
9971001 RelType rel = ctx.target ->getDynRel (type);
9981002 if (oneof<R_GOT, RE_LOONGARCH_GOT>(expr) ||
999- (rel == ctx.target ->symbolicRel && !sym.isPreemptible )) {
1003+ ((rel == ctx.target ->symbolicRel ||
1004+ (ctx.arg .emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) &&
1005+ !sym.isPreemptible )) {
10001006 addRelativeReloc<true >(ctx, *sec, offset, sym, addend, expr, type);
10011007 return ;
10021008 }
@@ -1005,24 +1011,6 @@ void RelocScan::process(RelExpr expr, RelType type, uint64_t offset,
10051011 rel = ctx.target ->relativeRel ;
10061012 std::lock_guard<std::mutex> lock (ctx.relocMutex );
10071013 Partition &part = sec->getPartition (ctx);
1008- if (ctx.arg .emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
1009- // For a preemptible symbol, we can't use a relative relocation. For an
1010- // undefined symbol, we can't compute offset at link-time and use a
1011- // relative relocation. Use a symbolic relocation instead.
1012- if (sym.isPreemptible ) {
1013- part.relaDyn ->addSymbolReloc (type, *sec, offset, sym, addend, type);
1014- } else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0 ) {
1015- // When symbol values are determined in
1016- // finalizeAddressDependentContent, some .relr.auth.dyn relocations
1017- // may be moved to .rela.dyn.
1018- sec->addReloc ({expr, type, offset, addend, &sym});
1019- part.relrAuthDyn ->relocs .push_back ({sec, sec->relocs ().size () - 1 });
1020- } else {
1021- part.relaDyn ->addReloc ({R_AARCH64_AUTH_RELATIVE, sec, offset, false ,
1022- sym, addend, R_ABS});
1023- }
1024- return ;
1025- }
10261014 if (LLVM_UNLIKELY (type == ctx.target ->iRelSymbolicRel )) {
10271015 if (sym.isPreemptible ) {
10281016 auto diag = Err (ctx);
0 commit comments