Skip to content

Commit 7c01a90

Browse files
authored
[BOLT] Refactor handling of branch targets. NFCI (#165828)
Refactor code that verifies external branch destinations and creates secondary entry points.
1 parent f6d6d2d commit 7c01a90

File tree

4 files changed

+37
-26
lines changed

4 files changed

+37
-26
lines changed

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,16 @@ class BinaryContext {
932932
std::pair<const MCSymbol *, uint64_t>
933933
handleAddressRef(uint64_t Address, BinaryFunction &BF, bool IsPCRel);
934934

935+
/// When \p Address inside function \p BF is a target of a control transfer
936+
/// instruction (branch) from another function, return a corresponding symbol
937+
/// that should be used by the branch. For example, main or secondary entry
938+
/// point.
939+
///
940+
/// If \p Address is an invalid destination, such as a constant island, return
941+
/// nullptr and mark \p BF as ignored, since we cannot properly handle a
942+
/// branch to a constant island.
943+
MCSymbol *handleExternalBranchTarget(uint64_t Address, BinaryFunction &BF);
944+
935945
/// Analyze memory contents at the given \p Address and return the type of
936946
/// memory contents (such as a possible jump table).
937947
MemoryContentsType analyzeMemoryAt(uint64_t Address, BinaryFunction &BF);

bolt/lib/Core/BinaryContext.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,23 @@ BinaryContext::handleAddressRef(uint64_t Address, BinaryFunction &BF,
518518
return std::make_pair(TargetSymbol, 0);
519519
}
520520

521+
MCSymbol *BinaryContext::handleExternalBranchTarget(uint64_t Address,
522+
BinaryFunction &BF) {
523+
if (BF.isInConstantIsland(Address)) {
524+
BF.setIgnored();
525+
this->outs() << "BOLT-WARNING: ignoring entry point at address 0x"
526+
<< Twine::utohexstr(Address)
527+
<< " in constant island of function " << BF << '\n';
528+
return nullptr;
529+
}
530+
531+
const uint64_t Offset = Address - BF.getAddress();
532+
assert(Offset < BF.getSize() &&
533+
"Address should be inside the referenced function");
534+
535+
return Offset ? BF.addEntryPointAtOffset(Offset) : BF.getSymbol();
536+
}
537+
521538
MemoryContentsType BinaryContext::analyzeMemoryAt(uint64_t Address,
522539
BinaryFunction &BF) {
523540
if (!isX86())
@@ -1399,17 +1416,10 @@ void BinaryContext::processInterproceduralReferences() {
13991416
<< Function.getPrintName() << " and "
14001417
<< TargetFunction->getPrintName() << '\n';
14011418
}
1402-
if (uint64_t Offset = Address - TargetFunction->getAddress()) {
1403-
if (!TargetFunction->isInConstantIsland(Address)) {
1404-
TargetFunction->addEntryPointAtOffset(Offset);
1405-
} else {
1406-
TargetFunction->setIgnored();
1407-
this->outs() << "BOLT-WARNING: Ignoring entry point at address 0x"
1408-
<< Twine::utohexstr(Address)
1409-
<< " in constant island of function " << *TargetFunction
1410-
<< '\n';
1411-
}
1412-
}
1419+
1420+
// Create an extra entry point if needed. Can also render the target
1421+
// function ignored if the reference is invalid.
1422+
handleExternalBranchTarget(Address, *TargetFunction);
14131423

14141424
continue;
14151425
}

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,21 +1697,12 @@ bool BinaryFunction::scanExternalRefs() {
16971697
if (!TargetFunction || ignoreFunctionRef(*TargetFunction))
16981698
continue;
16991699

1700-
const uint64_t FunctionOffset =
1701-
TargetAddress - TargetFunction->getAddress();
1702-
if (!TargetFunction->isInConstantIsland(TargetAddress)) {
1703-
BranchTargetSymbol =
1704-
FunctionOffset
1705-
? TargetFunction->addEntryPointAtOffset(FunctionOffset)
1706-
: TargetFunction->getSymbol();
1707-
} else {
1708-
TargetFunction->setIgnored();
1709-
BC.outs() << "BOLT-WARNING: Ignoring entry point at address 0x"
1710-
<< Twine::utohexstr(Address)
1711-
<< " in constant island of function " << *TargetFunction
1712-
<< '\n';
1700+
// Get a reference symbol for the function when address is a valid code
1701+
// reference.
1702+
BranchTargetSymbol =
1703+
BC.handleExternalBranchTarget(TargetAddress, *TargetFunction);
1704+
if (!BranchTargetSymbol)
17131705
continue;
1714-
}
17151706
}
17161707

17171708
// Can't find more references. Not creating relocations since we are not

bolt/test/AArch64/constant-island-entry.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
## Skip caller to check the identical warning is triggered from ScanExternalRefs().
1111
# RUN: llvm-bolt %t.exe -o %t.bolt -skip-funcs=caller 2>&1 | FileCheck %s
1212

13-
# CHECK: BOLT-WARNING: Ignoring entry point at address 0x{{[0-9a-f]+}} in constant island of function func
13+
# CHECK: BOLT-WARNING: ignoring entry point at address 0x{{[0-9a-f]+}} in constant island of function func
1414

1515
.globl func
1616
.type func, %function

0 commit comments

Comments
 (0)