Skip to content

Commit d98c6b9

Browse files
BOLT may never run the tentative code layout for cold BBs.
However, it might later require the addresses of cold BBs to compute PC-relative jumps between hot and cold fragments of a function. Since the addresses were never estimated, it uses 0x0 for cold BBs, resulting in incorrect estimated addresses for any instructions within them. As a result, LongJump often expands a branch that would otherwise fit in a single instruction into a short jump. For example, `relaxStub` might expand from: ```armasm b .Ltmp1234 ``` to: ```armasm adrp x16, .Ltmp1234 add x16, x16, :lo12:.Ltmp1234 br x16 ``` While this expansion is not wrong, it is unnecessary. Moreover, in some large binaries this expansion has lead to runtime crashes. This should be investigated further, as such expansions should not cause crashes.
1 parent d782119 commit d98c6b9

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

bolt/lib/Passes/LongJmp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,11 @@ uint64_t LongJmpPass::tentativeLayoutRelocMode(
382382
DotAddress += Func->estimateConstantIslandSize();
383383
++CurrentIndex;
384384
}
385+
if (!ColdLayoutDone) {
386+
errs() << "BOLT-ERROR: Did not perform tentative code layout for cold functions.\n";
387+
exit(1);
388+
}
389+
385390
// BBs
386391
for (BinaryFunction *Func : SortedFunctions)
387392
tentativeBBLayout(*Func);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// This test checks that tentative code layout for cold basic blocks runs
2+
// at least once, even when each function after the hot/cold frontier is not
3+
// emittable. This is done by ignoring each function using the 'skip-funcs' flag.
4+
// In a realistic scenario, this may happen when lite mode is enabled along
5+
// with a bolt profile.
6+
7+
REQUIRES: system-linux
8+
9+
RUN: %clang %cflags %p/../Inputs/asm_main.c -Wl,-q -o %t
10+
11+
RUN: not llvm-bolt %t -o %t.bolt -lite=1 -split-functions -split-all-cold \
12+
RUN: --skip-funcs="_init,_start,call_weak_fn/1,deregister_tm_clones/1,register_tm_clones/1,__do_global_dtors_aux/1,frame_dummy/1,main,foo,_fini" 2>&1 | FileCheck %s
13+
14+
CHECK: BOLT-ERROR: Did not perform tentative code layout for cold functions.

0 commit comments

Comments
 (0)