-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[lld][AArch64][ELF][PAC] Support .relr.auth.dyn
section
#87635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
500cfcf
25b03eb
4719599
411d04c
e68efcf
292b519
8a83e05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -544,7 +544,9 @@ class RelocationBaseSection : public SyntheticSection { | |
static bool classof(const SectionBase *d) { | ||
return SyntheticSection::classof(d) && | ||
(d->type == llvm::ELF::SHT_RELA || d->type == llvm::ELF::SHT_REL || | ||
d->type == llvm::ELF::SHT_RELR); | ||
d->type == llvm::ELF::SHT_RELR || | ||
(config->emachine == llvm::ELF::EM_AARCH64 && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. check d->type before config->emachine There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed, thanks, see e68efcf |
||
d->type == llvm::ELF::SHT_AARCH64_AUTH_RELR)); | ||
} | ||
int32_t dynamicTag, sizeDynamicTag; | ||
SmallVector<DynamicReloc, 0> relocs; | ||
|
@@ -592,15 +594,17 @@ class AndroidPackedRelocationSection final : public RelocationBaseSection { | |
}; | ||
|
||
struct RelativeReloc { | ||
uint64_t getOffset() const { return inputSec->getVA(offsetInSec); } | ||
uint64_t getOffset() const { | ||
return inputSec->getVA(inputSec->relocs()[relocIdx].offset); | ||
} | ||
|
||
const InputSectionBase *inputSec; | ||
uint64_t offsetInSec; | ||
size_t relocIdx; | ||
}; | ||
|
||
class RelrBaseSection : public SyntheticSection { | ||
public: | ||
RelrBaseSection(unsigned concurrency); | ||
RelrBaseSection(unsigned concurrency, bool isAArch64Auth = false); | ||
void mergeRels(); | ||
bool isNeeded() const override { | ||
return !relocs.empty() || | ||
|
@@ -618,7 +622,7 @@ template <class ELFT> class RelrSection final : public RelrBaseSection { | |
using Elf_Relr = typename ELFT::Relr; | ||
|
||
public: | ||
RelrSection(unsigned concurrency); | ||
RelrSection(unsigned concurrency, bool isAArch64Auth = false); | ||
|
||
bool updateAllocSize() override; | ||
size_t getSize() const override { return relrRelocs.size() * this->entsize; } | ||
|
@@ -1324,6 +1328,7 @@ struct Partition { | |
std::unique_ptr<PackageMetadataNote> packageMetadataNote; | ||
std::unique_ptr<RelocationBaseSection> relaDyn; | ||
std::unique_ptr<RelrBaseSection> relrDyn; | ||
std::unique_ptr<RelrBaseSection> relrAuthDyn; | ||
std::unique_ptr<VersionDefinitionSection> verDef; | ||
std::unique_ptr<SyntheticSection> verNeed; | ||
std::unique_ptr<VersionTableSection> verSym; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1445,9 +1445,33 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() { | |
in.mipsGot->updateAllocSize(); | ||
|
||
for (Partition &part : partitions) { | ||
// The R_AARCH64_AUTH_RELATIVE has a smaller addend field as bits [63:32] | ||
// encode the signing schema. We've put relocations in .relr.auth.dyn | ||
// during RelocationScanner::processAux, but the target VA for some of | ||
// them might be wider than 32 bits. We can only know the final VA at this | ||
// point, so move relocations with large values from .relr.auth.dyn to | ||
// .rela.dyn. | ||
if (part.relrAuthDyn) { | ||
auto it = llvm::remove_if( | ||
part.relrAuthDyn->relocs, [&part](const RelativeReloc &elem) { | ||
const Relocation &reloc = elem.inputSec->relocs()[elem.relocIdx]; | ||
if (isInt<32>(reloc.sym->getVA(reloc.addend))) | ||
return false; | ||
part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, elem.inputSec, | ||
reloc.offset, | ||
DynamicReloc::AddendOnlyWithTargetVA, | ||
*reloc.sym, reloc.addend, R_ABS}); | ||
// See also AArch64::relocate | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment can be moved to the previous one or just dropped. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved to the previous one, see e68efcf |
||
return true; | ||
}); | ||
changed |= (it != part.relrAuthDyn->relocs.end()); | ||
part.relrAuthDyn->relocs.erase(it, part.relrAuthDyn->relocs.end()); | ||
} | ||
changed |= part.relaDyn->updateAllocSize(); | ||
if (part.relrDyn) | ||
changed |= part.relrDyn->updateAllocSize(); | ||
if (part.relrAuthDyn) | ||
changed |= part.relrAuthDyn->updateAllocSize(); | ||
if (part.memtagGlobalDescriptors) | ||
changed |= part.memtagGlobalDescriptors->updateAllocSize(); | ||
} | ||
|
@@ -1598,6 +1622,14 @@ static void removeUnusedSyntheticSections() { | |
auto *sec = cast<SyntheticSection>(s); | ||
if (sec->getParent() && sec->isNeeded()) | ||
return false; | ||
// .relr.auth.dyn relocations may be moved to .rela.dyn in | ||
// finalizeAddressDependentContent, making .rela.dyn no longer empty. | ||
// Conservatively keep .rela.dyn. .relr.auth.dyn can be made empty, but | ||
// we would fail to remove it here. | ||
if (config->emachine == EM_AARCH64 && config->relrPackDynRelocs) | ||
if (auto *relSec = dyn_cast<RelocationBaseSection>(sec)) | ||
if (relSec == mainPart->relaDyn.get()) | ||
return false; | ||
unused.insert(sec); | ||
return true; | ||
}); | ||
|
@@ -1910,6 +1942,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { | |
part.relrDyn->mergeRels(); | ||
finalizeSynthetic(part.relrDyn.get()); | ||
} | ||
if (part.relrAuthDyn) { | ||
part.relrAuthDyn->mergeRels(); | ||
finalizeSynthetic(part.relrAuthDyn.get()); | ||
} | ||
|
||
finalizeSynthetic(part.dynSymTab.get()); | ||
finalizeSynthetic(part.gnuHashTab.get()); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Trailing period
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added, see e68efcf