Skip to content

Commit abd69b3

Browse files
authored
[BOLT] Handle internal calls in ValidateInternalCalls (#105736)
Move handling of all internal calls into the designated pass. Preserve NOPs and mark functions as non-simple on non-X86 platforms.
1 parent 2abed78 commit abd69b3

File tree

4 files changed

+77
-19
lines changed

4 files changed

+77
-19
lines changed

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,8 @@ class BinaryFunction {
16921692

16931693
void setPseudo(bool Pseudo) { IsPseudo = Pseudo; }
16941694

1695+
void setPreserveNops(bool Value) { PreserveNops = Value; }
1696+
16951697
BinaryFunction &setUsesGnuArgsSize(bool Uses = true) {
16961698
UsesGnuArgsSize = Uses;
16971699
return *this;

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,22 +1339,10 @@ Error BinaryFunction::disassemble() {
13391339
BC.getBinaryFunctionContainingAddress(TargetAddress))
13401340
TargetFunc->setIgnored();
13411341

1342-
if (IsCall && containsAddress(TargetAddress)) {
1343-
if (TargetAddress == getAddress()) {
1344-
// Recursive call.
1345-
TargetSymbol = getSymbol();
1346-
} else {
1347-
if (BC.isX86()) {
1348-
// Dangerous old-style x86 PIC code. We may need to freeze this
1349-
// function, so preserve the function as is for now.
1350-
PreserveNops = true;
1351-
} else {
1352-
BC.errs() << "BOLT-WARNING: internal call detected at 0x"
1353-
<< Twine::utohexstr(AbsoluteInstrAddr)
1354-
<< " in function " << *this << ". Skipping.\n";
1355-
IsSimple = false;
1356-
}
1357-
}
1342+
if (IsCall && TargetAddress == getAddress()) {
1343+
// A recursive call. Calls to internal blocks are handled by
1344+
// ValidateInternalCalls pass.
1345+
TargetSymbol = getSymbol();
13581346
}
13591347

13601348
if (!TargetSymbol) {

bolt/lib/Passes/ValidateInternalCalls.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,24 +302,27 @@ bool ValidateInternalCalls::analyzeFunction(BinaryFunction &Function) const {
302302
}
303303

304304
Error ValidateInternalCalls::runOnFunctions(BinaryContext &BC) {
305-
if (!BC.isX86())
306-
return Error::success();
307-
308305
// Look for functions that need validation. This should be pretty rare.
309306
std::set<BinaryFunction *> NeedsValidation;
310307
for (auto &BFI : BC.getBinaryFunctions()) {
311308
BinaryFunction &Function = BFI.second;
312309
for (BinaryBasicBlock &BB : Function) {
313310
for (MCInst &Inst : BB) {
314311
if (getInternalCallTarget(Function, Inst)) {
312+
BC.errs() << "BOLT-WARNING: internal call detected in function "
313+
<< Function << '\n';
315314
NeedsValidation.insert(&Function);
316315
Function.setSimple(false);
316+
Function.setPreserveNops(true);
317317
break;
318318
}
319319
}
320320
}
321321
}
322322

323+
if (!BC.isX86())
324+
return Error::success();
325+
323326
// Skip validation for non-relocation mode
324327
if (!BC.HasRelocations)
325328
return Error::success();

bolt/test/AArch64/internal-call.s

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
## Test that llvm-bolt detects internal calls and marks the containing function
2+
## as non-simple.
3+
4+
# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
5+
# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -static
6+
# RUN: llvm-bolt %t.exe -o %t.null --print-all 2>&1 | FileCheck %s
7+
8+
# CHECK: Binary Function "_start" after building cfg
9+
# CHECK: internal call detected in function _start
10+
# CHECK-NOT: Binary Function "_start" after validate-internal-calls
11+
12+
.text
13+
.globl _start
14+
.type _start, %function
15+
_start:
16+
.cfi_startproc
17+
.LBB00:
18+
mov x11, #0x1fff
19+
cmp x1, x11
20+
b.hi .Ltmp1
21+
22+
.entry1:
23+
movi v4.16b, #0x0
24+
movi v5.16b, #0x0
25+
subs x1, x1, #0x8
26+
b.lo .Ltmp2
27+
28+
.entry2:
29+
ld1 { v2.2d, v3.2d }, [x0], #32
30+
ld1 { v0.2d, v1.2d }, [x0], #32
31+
32+
.Ltmp2:
33+
uaddlp v4.4s, v4.8h
34+
uaddlp v4.2d, v4.4s
35+
mov x0, v4.d[0]
36+
mov x1, v4.d[1]
37+
add x0, x0, x1
38+
ret x30
39+
40+
.Ltmp1:
41+
mov x8, x30
42+
43+
.Lloop:
44+
add x5, x0, x9
45+
mov x1, #0xface
46+
movi v4.16b, #0x0
47+
movi v5.16b, #0x0
48+
bl .entry2
49+
add x4, x4, x0
50+
mov x0, x5
51+
sub x7, x7, x10
52+
cmp x7, x11
53+
b.hi .Lloop
54+
55+
mov x1, x7
56+
bl .entry1
57+
add x0, x4, x0
58+
mov x30, x8
59+
ret x30
60+
61+
.cfi_endproc
62+
.size _start, .-_start
63+
64+
## Force relocation mode.
65+
.reloc 0, R_AARCH64_NONE

0 commit comments

Comments
 (0)