Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions bolt/lib/Core/BinaryBasicBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,18 @@ bool BinaryBasicBlock::validateSuccessorInvariants() {
Valid &= (Sym == Function->getFunctionEndLabel() ||
Sym == Function->getFunctionEndLabel(getFragmentNum()));
if (!Valid) {
BC.errs() << "BOLT-WARNING: Jump table contains illegal entry: "
<< Sym->getName() << "\n";
const BinaryFunction *TargetBF = BC.getFunctionForSymbol(Sym);
if (TargetBF) {
// It's possible for another function to be in the jump table entry
// as a result of built-in unreachable.
Valid = true;
} else {
BC.errs() << "BOLT-WARNING: Jump table contains illegal entry: "
<< Sym->getName() << "\n";
}
}
if (!Valid)
break;
}
}
} else {
Expand Down
4 changes: 3 additions & 1 deletion bolt/lib/Core/BinaryFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1959,7 +1959,9 @@ void BinaryFunction::postProcessJumpTables() {
return EntryAddress == Parent->getAddress() + Parent->getSize();
});
if (IsBuiltinUnreachable) {
MCSymbol *Label = getOrCreateLocalLabel(EntryAddress, true);
BinaryFunction *TargetBF = BC.getBinaryFunctionAtAddress(EntryAddress);
MCSymbol *Label = TargetBF ? TargetBF->getSymbol()
: getOrCreateLocalLabel(EntryAddress, true);
JT.Entries.push_back(Label);
continue;
}
Expand Down
5 changes: 1 addition & 4 deletions bolt/lib/Passes/IndirectCallPromotion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,7 @@ IndirectCallPromotion::getCallTargets(BinaryBasicBlock &BB,
for (size_t I = Range.first; I < Range.second; ++I, JI += JIAdj) {
MCSymbol *Entry = JT->Entries[I];
const BinaryBasicBlock *ToBB = BF.getBasicBlockForLabel(Entry);
assert(ToBB || Entry == BF.getFunctionEndLabel() ||
Entry == BF.getFunctionEndLabel(FragmentNum::cold()));
if (Entry == BF.getFunctionEndLabel() ||
Entry == BF.getFunctionEndLabel(FragmentNum::cold()))
if (!ToBB)
continue;
const Location To(Entry);
const BinaryBasicBlock::BinaryBranchInfo &BI = BB.getBranchInfo(*ToBB);
Expand Down
87 changes: 87 additions & 0 deletions bolt/test/X86/jump-table-ambiguous-unreachable.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
## Check that llvm-bolt correctly updates ambiguous jump table entries that
## can correspond to either builtin_unreachable() or could be a pointer to
## the next function.

# REQUIRES: system-linux

# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
# RUN: %clang %cflags %t.o -o %t.exe -no-pie -Wl,-q

# RUN: llvm-bolt %t.exe --print-normalized --print-only=foo -o %t.out \
# RUN: 2>&1 | FileCheck %s



.text
.globl _start
.type _start, %function
_start:
.cfi_startproc
call foo
ret
.cfi_endproc
.size _start, .-_start

.globl foo
.type foo, %function
foo:
.cfi_startproc
.LBB00:
movq 0x8(%rdi), %rdi
movzbl 0x1(%rdi), %eax
.LBB00_br:
jmpq *"JUMP_TABLE/foo.0"(,%rax,8)
# CHECK: jmpq {{.*}} # JUMPTABLE
# CHECK-NEXT: Successors: {{.*}}, {{.*}}, {{.*}}, {{.*}}, {{.*}}

.Ltmp87085:
xorl %eax, %eax
retq

.Ltmp87086:
cmpb $0x0, 0x8(%rdi)
setne %al
retq

.Ltmp87088:
movb $0x1, %al
retq

.Ltmp87087:
movzbl 0x14(%rdi), %eax
andb $0x2, %al
shrb %al
retq

.cfi_endproc
.size foo, .-foo

.globl bar
.type bar, %function
bar:
.cfi_startproc
ret
.cfi_endproc
.size bar, .-bar

# Jump tables
.section .rodata
.global jump_table
jump_table:
"JUMP_TABLE/foo.0":
.quad bar
.quad .Ltmp87085
.quad bar
.quad .Ltmp87086
.quad .Ltmp87087
.quad .LBB00
.quad .Ltmp87088
.quad bar
.quad .LBB00

# CHECK: Jump table {{.*}} for function foo
# CHECK-NEXT: 0x{{.*}} : bar
# CHECK-NEXT: 0x{{.*}} :
# CHECK-NEXT: 0x{{.*}} : bar
# CHECK-NEXT: 0x{{.*}} :
# CHECK-NEXT: 0x{{.*}} :
Loading