@@ -1454,9 +1454,32 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
1454
1454
in.mipsGot ->updateAllocSize ();
1455
1455
1456
1456
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
+ }
1457
1478
changed |= part.relaDyn ->updateAllocSize ();
1458
1479
if (part.relrDyn )
1459
1480
changed |= part.relrDyn ->updateAllocSize ();
1481
+ if (part.relrAuthDyn )
1482
+ changed |= part.relrAuthDyn ->updateAllocSize ();
1460
1483
if (part.memtagGlobalDescriptors )
1461
1484
changed |= part.memtagGlobalDescriptors ->updateAllocSize ();
1462
1485
}
@@ -1614,6 +1637,14 @@ static void removeUnusedSyntheticSections() {
1614
1637
auto *sec = cast<SyntheticSection>(s);
1615
1638
if (sec->getParent () && sec->isNeeded ())
1616
1639
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 ;
1617
1648
unused.insert (sec);
1618
1649
return true ;
1619
1650
});
@@ -1926,6 +1957,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
1926
1957
part.relrDyn ->mergeRels ();
1927
1958
finalizeSynthetic (part.relrDyn .get ());
1928
1959
}
1960
+ if (part.relrAuthDyn ) {
1961
+ part.relrAuthDyn ->mergeRels ();
1962
+ finalizeSynthetic (part.relrAuthDyn .get ());
1963
+ }
1929
1964
1930
1965
finalizeSynthetic (part.dynSymTab .get ());
1931
1966
finalizeSynthetic (part.gnuHashTab .get ());
0 commit comments