Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 29 additions & 14 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2293,6 +2293,31 @@ bool ThunkCreator::normalizeExistingThunk(Relocation &rel, uint64_t src) {
return false;
}

// When indirect branches are restricted, such as AArch64 BTI Thunks may need
// to target a linker generated landing pad instead of the target. This needs
// to be done once per pass as the need for a BTI thunk is dependent whether
// a thunk is short or long. We iterate over all the thunks to make sure we
// catch thunks that have been created but are no longer live. Non-live thunks
// are not reachable via normalizeExistingThunk() but are still written.
bool ThunkCreator::addSyntheticLandingPads() {
bool addressesChanged = false;
for (Thunk *t : allThunks) {
if (t->needsSyntheticLandingPad()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can early return

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've flipped the condition so it can continue. This loses a level of indentation. We need to go through all the thunks so we can't return.

Thunk *lpt;
bool isNew;
auto &dr = cast<Defined>(t->destination);
std::tie(lpt, isNew) = getSyntheticLandingPad(dr, t->addend);
if (isNew) {
addressesChanged = true;
ThunkSection *ts = getISThunkSec(cast<InputSection>(dr.section));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The used-once variable can be avoided

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK removed.

ts->addThunk(lpt);
}
t->landingPad = lpt->getThunkTargetSym();
}
}
return addressesChanged;
}

// Process all relocations from the InputSections that have been assigned
// to InputSectionDescriptions and redirect through Thunks if needed. The
// function should be called iteratively until it returns false.
Expand Down Expand Up @@ -2326,6 +2351,9 @@ bool ThunkCreator::createThunks(uint32_t pass,
if (pass == 0 && ctx.target->getThunkSectionSpacing())
createInitialThunkSections(outputSections);

if (ctx.arg.emachine == EM_AARCH64)
addressesChanged = addSyntheticLandingPads();

// Create all the Thunks and insert them into synthetic ThunkSections. The
// ThunkSections are later inserted back into InputSectionDescriptions.
// We separate the creation of ThunkSections from the insertion of the
Expand Down Expand Up @@ -2360,20 +2388,7 @@ bool ThunkCreator::createThunks(uint32_t pass,
ts = getISDThunkSec(os, isec, isd, rel, src);
ts->addThunk(t);
thunks[t->getThunkTargetSym()] = t;

// When indirect branches are restricted, such as AArch64 BTI
// Thunks may need to target a linker generated landing pad
// instead of the target.
if (t->needsSyntheticLandingPad()) {
Thunk *lpt;
auto &dr = cast<Defined>(t->destination);
std::tie(lpt, isNew) = getSyntheticLandingPad(dr, t->addend);
if (isNew) {
ts = getISThunkSec(cast<InputSection>(dr.section));
ts->addThunk(lpt);
}
t->landingPad = lpt->getThunkTargetSym();
}
allThunks.push_back(t);
}

// Redirect relocation to Thunk, we never go via the PLT to a Thunk
Expand Down
5 changes: 5 additions & 0 deletions lld/ELF/Relocations.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ class ThunkCreator {

bool normalizeExistingThunk(Relocation &rel, uint64_t src);

bool addSyntheticLandingPads();

Ctx &ctx;

// Record all the available Thunks for a (Symbol, addend) pair, where Symbol
Expand Down Expand Up @@ -216,6 +218,9 @@ class ThunkCreator {
Thunk *>
landingPadsBySectionAndAddend;

// All the nonLandingPad thunks that have been created, in order of creation.
std::vector<Thunk *> allThunks;

// The number of completed passes of createThunks this permits us
// to do one time initialization on Pass 0 and put a limit on the
// number of times it can be called to prevent infinite loops.
Expand Down
Loading