mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 07:31:28 +00:00
[BOLT] Fix local out-of-range stub issue in LongJmp (#73918)
If a local stub is out-of-range, at LongJmp we will try to find another local stub first. However, The original implementation do not work as expected and it leads to an infinite loop between replaceTargetWithStub and fixBranches. After this patch, we first convert the target of BB back to the target of the local stub, and then look up for other valid local stubs and so on.
This commit is contained in:
parent
af999c4be9
commit
fdb13cf531
@ -202,10 +202,23 @@ LongJmpPass::replaceTargetWithStub(BinaryBasicBlock &BB, MCInst &Inst,
|
||||
}
|
||||
} else if (LocalStubsIter != Stubs.end() &&
|
||||
LocalStubsIter->second.count(TgtBB)) {
|
||||
// If we are replacing a local stub (because it is now out of range),
|
||||
// use its target instead of creating a stub to jump to another stub
|
||||
// The TgtBB and TgtSym now are the local out-of-range stub and its label.
|
||||
// So, we are attempting to restore BB to its previous state without using
|
||||
// this stub.
|
||||
TgtSym = BC.MIB->getTargetSymbol(*TgtBB->begin());
|
||||
TgtBB = BB.getSuccessor(TgtSym, BI);
|
||||
assert(TgtSym &&
|
||||
"First instruction is expected to contain a target symbol.");
|
||||
BinaryBasicBlock *TgtBBSucc = TgtBB->getSuccessor(TgtSym, BI);
|
||||
|
||||
// TgtBB might have no successor. e.g. a stub for a function call.
|
||||
if (TgtBBSucc) {
|
||||
BB.replaceSuccessor(TgtBB, TgtBBSucc, BI.Count, BI.MispredictedCount);
|
||||
assert(TgtBB->getExecutionCount() >= BI.Count &&
|
||||
"At least equal or greater than the branch count.");
|
||||
TgtBB->setExecutionCount(TgtBB->getExecutionCount() - BI.Count);
|
||||
}
|
||||
|
||||
TgtBB = TgtBBSucc;
|
||||
}
|
||||
|
||||
BinaryBasicBlock *StubBB = lookupLocalStub(BB, Inst, TgtSym, DotAddress);
|
||||
|
Loading…
Reference in New Issue
Block a user