Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 49f2679

Browse filesBrowse files
committed
Fix handling of unreachable loops of BBs
1 parent c11b901 commit 49f2679
Copy full SHA for 49f2679

File tree

Expand file treeCollapse file tree

3 files changed

+68
-14
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+68
-14
lines changed

‎bolt/lib/Passes/PAuthGadgetScanner.cpp

Copy file name to clipboardExpand all lines: bolt/lib/Passes/PAuthGadgetScanner.cpp
+38-11Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,21 +1349,42 @@ void FunctionAnalysisContext::findUnsafeUses(
13491349
BF.dump();
13501350
});
13511351

1352+
bool UnreachableBBReported = false;
13521353
if (BF.hasCFG()) {
1353-
// Warn on basic blocks being unreachable according to BOLT, as this
1354-
// likely means CFG is imprecise.
1354+
// Warn on basic blocks being unreachable according to BOLT (at most once
1355+
// per BinaryFunction), as this likely means the CFG reconstructed by BOLT
1356+
// is imprecise. A basic block can be
1357+
// * reachable from an entry basic block - a hopefully correct non-empty
1358+
// state is propagated to that basic block sooner or later. All basic
1359+
// blocks are expected to belong to this category under normal conditions.
1360+
// * reachable from a "directly unreachable" BB (a basic block that has no
1361+
// direct predecessors and this is not because it is an entry BB) - *some*
1362+
// non-empty state is propagated to this basic block sooner or later, as
1363+
// the initial state of directly unreachable basic blocks is
1364+
// pessimistically initialized to "all registers are unsafe"
1365+
// - a warning can be printed for the "directly unreachable" basic block
1366+
// * neither reachable from an entry nor from a "directly unreachable" BB
1367+
// (such as if this BB is in an isolated loop of basic blocks) - the final
1368+
// state is computed to be empty for this basic block
1369+
// - a warning can be printed for this basic block
13551370
for (BinaryBasicBlock &BB : BF) {
1356-
if (!BB.pred_empty() || BB.isEntryPoint())
1371+
MCInst *FirstInst = BB.getFirstNonPseudoInstr();
1372+
// Skip empty basic block early for simplicity.
1373+
if (!FirstInst)
1374+
continue;
1375+
1376+
bool IsDirectlyUnreachable = BB.pred_empty() && !BB.isEntryPoint();
1377+
bool HasNoStateComputed = Analysis->getStateBefore(*FirstInst).empty();
1378+
if (!IsDirectlyUnreachable && !HasNoStateComputed)
13571379
continue;
1358-
// Arbitrarily attach the report to the first instruction of BB.
1359-
MCInst *InstToReport = BB.getFirstNonPseudoInstr();
1360-
if (!InstToReport)
1361-
continue; // BB has no real instructions
13621380

1381+
// Arbitrarily attach the report to the first instruction of BB.
13631382
Reports.push_back(
1364-
make_generic_report(MCInstReference::get(InstToReport, BF),
1365-
"Warning: no predecessor basic blocks detected "
1366-
"(possibly incomplete CFG)"));
1383+
make_generic_report(MCInstReference::get(FirstInst, BF),
1384+
"Warning: the function has unreachable basic "
1385+
"blocks (possibly incomplete CFG)"));
1386+
UnreachableBBReported = true;
1387+
break; // One warning per function.
13671388
}
13681389
}
13691390

@@ -1372,7 +1393,13 @@ void FunctionAnalysisContext::findUnsafeUses(
13721393
return;
13731394

13741395
const SrcState &S = Analysis->getStateBefore(Inst);
1375-
assert(!S.empty() && "Instruction has no associated state");
1396+
if (S.empty()) {
1397+
LLVM_DEBUG(
1398+
{ traceInst(BC, "Instruction has no state, skipping", Inst); });
1399+
assert(UnreachableBBReported && "Should be reported at least once");
1400+
(void)UnreachableBBReported;
1401+
return;
1402+
}
13761403

13771404
if (auto Report = shouldReportReturnGadget(BC, Inst, S))
13781405
Reports.push_back(*Report);

‎bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s

Copy file name to clipboardExpand all lines: bolt/test/binary-analysis/AArch64/gs-pacret-autiasp.s
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ f_callclobbered_calleesaved:
215215
.globl f_unreachable_instruction
216216
.type f_unreachable_instruction,@function
217217
f_unreachable_instruction:
218-
// CHECK-LABEL: GS-PAUTH: Warning: no predecessor basic blocks detected (possibly incomplete CFG) in function f_unreachable_instruction, basic block {{[0-9a-zA-Z.]+}}, at address
218+
// CHECK-LABEL: GS-PAUTH: Warning: the function has unreachable basic blocks (possibly incomplete CFG) in function f_unreachable_instruction, basic block {{[0-9a-zA-Z.]+}}, at address
219219
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: add x0, x1, x2
220220
// CHECK-NOT: instructions that write to the affected registers after any authentication are:
221221
// CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_unreachable_instruction, basic block {{[0-9a-zA-Z.]+}}, at address

‎bolt/test/binary-analysis/AArch64/gs-pauth-calls.s

Copy file name to clipboardExpand all lines: bolt/test/binary-analysis/AArch64/gs-pauth-calls.s
+29-2Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,7 +1441,7 @@ printed_instrs_nocfg:
14411441
.globl bad_unreachable_call
14421442
.type bad_unreachable_call,@function
14431443
bad_unreachable_call:
1444-
// CHECK-LABEL: GS-PAUTH: Warning: no predecessor basic blocks detected (possibly incomplete CFG) in function bad_unreachable_call, basic block {{[^,]+}}, at address
1444+
// CHECK-LABEL: GS-PAUTH: Warning: the function has unreachable basic blocks (possibly incomplete CFG) in function bad_unreachable_call, basic block {{[^,]+}}, at address
14451445
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: blr x0
14461446
// CHECK-NOT: instructions that write to the affected registers after any authentication are:
14471447
// CHECK-LABEL: GS-PAUTH: non-protected call found in function bad_unreachable_call, basic block {{[^,]+}}, at address
@@ -1465,7 +1465,7 @@ bad_unreachable_call:
14651465
.type good_unreachable_call,@function
14661466
good_unreachable_call:
14671467
// CHECK-NOT: non-protected call{{.*}}good_unreachable_call
1468-
// CHECK-LABEL: GS-PAUTH: Warning: no predecessor basic blocks detected (possibly incomplete CFG) in function good_unreachable_call, basic block {{[^,]+}}, at address
1468+
// CHECK-LABEL: GS-PAUTH: Warning: the function has unreachable basic blocks (possibly incomplete CFG) in function good_unreachable_call, basic block {{[^,]+}}, at address
14691469
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: autia x0, x1
14701470
// CHECK-NOT: instructions that write to the affected registers after any authentication are:
14711471
// CHECK-NOT: non-protected call{{.*}}good_unreachable_call
@@ -1485,6 +1485,33 @@ good_unreachable_call:
14851485
ret
14861486
.size good_unreachable_call, .-good_unreachable_call
14871487

1488+
.globl unreachable_loop_of_bbs
1489+
.type unreachable_loop_of_bbs,@function
1490+
unreachable_loop_of_bbs:
1491+
// CHECK-NOT: unreachable basic blocks{{.*}}unreachable_loop_of_bbs
1492+
// CHECK-NOT: non-protected call{{.*}}unreachable_loop_of_bbs
1493+
// CHECK-LABEL: GS-PAUTH: Warning: the function has unreachable basic blocks (possibly incomplete CFG) in function unreachable_loop_of_bbs, basic block {{[^,]+}}, at address
1494+
// CHECK-NEXT: The instruction is {{[0-9a-f]+}}: blr x0
1495+
// CHECK-NOT: unreachable basic blocks{{.*}}unreachable_loop_of_bbs
1496+
// CHECK-NOT: non-protected call{{.*}}unreachable_loop_of_bbs
1497+
paciasp
1498+
stp x29, x30, [sp, #-16]!
1499+
mov x29, sp
1500+
b .Lreachable_epilogue_bb
1501+
1502+
.Lfirst_unreachable_bb:
1503+
blr x0 // <-- this call is not analyzed
1504+
b .Lsecond_unreachable_bb
1505+
.Lsecond_unreachable_bb:
1506+
blr x1 // <-- this call is not analyzed
1507+
b .Lfirst_unreachable_bb
1508+
1509+
.Lreachable_epilogue_bb:
1510+
ldp x29, x30, [sp], #16
1511+
autiasp
1512+
ret
1513+
.size unreachable_loop_of_bbs, .-unreachable_loop_of_bbs
1514+
14881515
.globl main
14891516
.type main,@function
14901517
main:

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.