@@ -1454,9 +1454,32 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
14541454 in.mipsGot ->updateAllocSize ();
14551455
14561456 for (Partition &part : partitions) {
1457+ // The R_AARCH64_AUTH_RELATIVE has a smaller addend field as bits [63:32]
1458+ // encode the signing schema. We've put relocations in .relr.auth.dyn
1459+ // during RelocationScanner::processAux, but the target VA for some of
1460+ // them might be wider than 32 bits. We can only know the final VA at this
1461+ // point, so move relocations with large values from .relr.auth.dyn to
1462+ // .rela.dyn. See also AArch64::relocate.
1463+ if (part.relrAuthDyn ) {
1464+ auto it = llvm::remove_if (
1465+ part.relrAuthDyn ->relocs , [&part](const RelativeReloc &elem) {
1466+ const Relocation &reloc = elem.inputSec ->relocs ()[elem.relocIdx ];
1467+ if (isInt<32 >(reloc.sym ->getVA (reloc.addend )))
1468+ return false ;
1469+ part.relaDyn ->addReloc ({R_AARCH64_AUTH_RELATIVE, elem.inputSec ,
1470+ reloc.offset ,
1471+ DynamicReloc::AddendOnlyWithTargetVA,
1472+ *reloc.sym , reloc.addend , R_ABS});
1473+ return true ;
1474+ });
1475+ changed |= (it != part.relrAuthDyn ->relocs .end ());
1476+ part.relrAuthDyn ->relocs .erase (it, part.relrAuthDyn ->relocs .end ());
1477+ }
14571478 changed |= part.relaDyn ->updateAllocSize ();
14581479 if (part.relrDyn )
14591480 changed |= part.relrDyn ->updateAllocSize ();
1481+ if (part.relrAuthDyn )
1482+ changed |= part.relrAuthDyn ->updateAllocSize ();
14601483 if (part.memtagGlobalDescriptors )
14611484 changed |= part.memtagGlobalDescriptors ->updateAllocSize ();
14621485 }
@@ -1614,6 +1637,14 @@ static void removeUnusedSyntheticSections() {
16141637 auto *sec = cast<SyntheticSection>(s);
16151638 if (sec->getParent () && sec->isNeeded ())
16161639 return false ;
1640+ // .relr.auth.dyn relocations may be moved to .rela.dyn in
1641+ // finalizeAddressDependentContent, making .rela.dyn no longer empty.
1642+ // Conservatively keep .rela.dyn. .relr.auth.dyn can be made empty, but
1643+ // we would fail to remove it here.
1644+ if (config->emachine == EM_AARCH64 && config->relrPackDynRelocs )
1645+ if (auto *relSec = dyn_cast<RelocationBaseSection>(sec))
1646+ if (relSec == mainPart->relaDyn .get ())
1647+ return false ;
16171648 unused.insert (sec);
16181649 return true ;
16191650 });
@@ -1926,6 +1957,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
19261957 part.relrDyn ->mergeRels ();
19271958 finalizeSynthetic (part.relrDyn .get ());
19281959 }
1960+ if (part.relrAuthDyn ) {
1961+ part.relrAuthDyn ->mergeRels ();
1962+ finalizeSynthetic (part.relrAuthDyn .get ());
1963+ }
19291964
19301965 finalizeSynthetic (part.dynSymTab .get ());
19311966 finalizeSynthetic (part.gnuHashTab .get ());
0 commit comments