[BOLT] Refactor handling of branch targets. NFCI (#165828)

Refactor code that verifies external branch destinations and creates
secondary entry points.
This commit is contained in:
Maksim Panchenko 2025-10-31 08:56:30 -07:00 committed by GitHub
parent f6d6d2d5a2
commit 7c01a90545
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 37 additions and 26 deletions

View file

@ -932,6 +932,16 @@ public:
std::pair<const MCSymbol *, uint64_t>
handleAddressRef(uint64_t Address, BinaryFunction &BF, bool IsPCRel);
/// When \p Address inside function \p BF is a target of a control transfer
/// instruction (branch) from another function, return a corresponding symbol
/// that should be used by the branch. For example, main or secondary entry
/// point.
///
/// If \p Address is an invalid destination, such as a constant island, return
/// nullptr and mark \p BF as ignored, since we cannot properly handle a
/// branch to a constant island.
MCSymbol *handleExternalBranchTarget(uint64_t Address, BinaryFunction &BF);
/// Analyze memory contents at the given \p Address and return the type of
/// memory contents (such as a possible jump table).
MemoryContentsType analyzeMemoryAt(uint64_t Address, BinaryFunction &BF);

View file

@ -518,6 +518,23 @@ BinaryContext::handleAddressRef(uint64_t Address, BinaryFunction &BF,
return std::make_pair(TargetSymbol, 0);
}
MCSymbol *BinaryContext::handleExternalBranchTarget(uint64_t Address,
BinaryFunction &BF) {
if (BF.isInConstantIsland(Address)) {
BF.setIgnored();
this->outs() << "BOLT-WARNING: ignoring entry point at address 0x"
<< Twine::utohexstr(Address)
<< " in constant island of function " << BF << '\n';
return nullptr;
}
const uint64_t Offset = Address - BF.getAddress();
assert(Offset < BF.getSize() &&
"Address should be inside the referenced function");
return Offset ? BF.addEntryPointAtOffset(Offset) : BF.getSymbol();
}
MemoryContentsType BinaryContext::analyzeMemoryAt(uint64_t Address,
BinaryFunction &BF) {
if (!isX86())
@ -1399,17 +1416,10 @@ void BinaryContext::processInterproceduralReferences() {
<< Function.getPrintName() << " and "
<< TargetFunction->getPrintName() << '\n';
}
if (uint64_t Offset = Address - TargetFunction->getAddress()) {
if (!TargetFunction->isInConstantIsland(Address)) {
TargetFunction->addEntryPointAtOffset(Offset);
} else {
TargetFunction->setIgnored();
this->outs() << "BOLT-WARNING: Ignoring entry point at address 0x"
<< Twine::utohexstr(Address)
<< " in constant island of function " << *TargetFunction
<< '\n';
}
}
// Create an extra entry point if needed. Can also render the target
// function ignored if the reference is invalid.
handleExternalBranchTarget(Address, *TargetFunction);
continue;
}

View file

@ -1697,21 +1697,12 @@ bool BinaryFunction::scanExternalRefs() {
if (!TargetFunction || ignoreFunctionRef(*TargetFunction))
continue;
const uint64_t FunctionOffset =
TargetAddress - TargetFunction->getAddress();
if (!TargetFunction->isInConstantIsland(TargetAddress)) {
BranchTargetSymbol =
FunctionOffset
? TargetFunction->addEntryPointAtOffset(FunctionOffset)
: TargetFunction->getSymbol();
} else {
TargetFunction->setIgnored();
BC.outs() << "BOLT-WARNING: Ignoring entry point at address 0x"
<< Twine::utohexstr(Address)
<< " in constant island of function " << *TargetFunction
<< '\n';
// Get a reference symbol for the function when address is a valid code
// reference.
BranchTargetSymbol =
BC.handleExternalBranchTarget(TargetAddress, *TargetFunction);
if (!BranchTargetSymbol)
continue;
}
}
// Can't find more references. Not creating relocations since we are not

View file

@ -10,7 +10,7 @@
## Skip caller to check the identical warning is triggered from ScanExternalRefs().
# RUN: llvm-bolt %t.exe -o %t.bolt -skip-funcs=caller 2>&1 | FileCheck %s
# CHECK: BOLT-WARNING: Ignoring entry point at address 0x{{[0-9a-f]+}} in constant island of function func
# CHECK: BOLT-WARNING: ignoring entry point at address 0x{{[0-9a-f]+}} in constant island of function func
.globl func
.type func, %function