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
16 changes: 12 additions & 4 deletions bolt/lib/Core/MCPlusBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ using namespace bolt;
using namespace MCPlus;

namespace opts {
cl::opt<bool>
TerminalHLT("terminal-x86-hlt",
cl::desc("Assume that execution stops at x86 HLT instruction"),
cl::init(true), cl::Hidden, cl::cat(BoltCategory));

cl::opt<bool>
TerminalTrap("terminal-trap",
cl::desc("Assume that execution stops at trap instruction"),
Expand Down Expand Up @@ -132,10 +137,13 @@ bool MCPlusBuilder::equals(const MCSpecifierExpr &A, const MCSpecifierExpr &B,
}

bool MCPlusBuilder::isTerminator(const MCInst &Inst) const {
return (opts::TerminalTrap && Info->get(Inst.getOpcode()).isTrap()) ||
Analysis->isTerminator(Inst)
? !isX86HLT(Inst)
: false;
if (isX86HLT(Inst))
return opts::TerminalHLT;

if (Info->get(Inst.getOpcode()).isTrap())
return opts::TerminalTrap;

return Analysis->isTerminator(Inst);
}

void MCPlusBuilder::setTailCall(MCInst &Inst) const {
Expand Down
5 changes: 4 additions & 1 deletion bolt/lib/Rewrite/RewriteInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ extern cl::opt<bool> KeepNops;
extern cl::opt<bool> Lite;
extern cl::list<std::string> ReorderData;
extern cl::opt<bolt::ReorderFunctions::ReorderType> ReorderFunctions;
extern cl::opt<bool> TerminalHLT;
extern cl::opt<bool> TerminalTrap;
extern cl::opt<bool> TimeBuild;
extern cl::opt<bool> TimeRewrite;
Expand Down Expand Up @@ -2177,7 +2178,9 @@ void RewriteInstance::adjustCommandLineOptions() {
if (!opts::KeepNops.getNumOccurrences())
opts::KeepNops = true;

// Linux kernel may resume execution after a trap instruction in some cases.
// Linux kernel may resume execution after a trap or x86 HLT instruction.
if (!opts::TerminalHLT.getNumOccurrences())
opts::TerminalHLT = false;
if (!opts::TerminalTrap.getNumOccurrences())
opts::TerminalTrap = false;
}
Expand Down
17 changes: 0 additions & 17 deletions bolt/test/X86/cfg_build_hlt.s

This file was deleted.

24 changes: 24 additions & 0 deletions bolt/test/X86/hlt-terminator.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## Check that HLT instruction is handled differently depending on the flags.
## It's a terminator in the user-level code, but the execution can resume in
## ring 0.

# RUN: %clang %cflags %s -static -o %t.exe -nostdlib
# RUN: llvm-bolt %t.exe --print-cfg --print-only=main --terminal-x86-hlt=0 \
# RUN: -o %t.ring0 2>&1 | FileCheck %s --check-prefix=CHECK-RING0
# RUN: llvm-bolt %t.exe --print-cfg --print-only=main \
# RUN: -o %t.ring3 2>&1 | FileCheck %s --check-prefix=CHECK-RING3
# RUN: llvm-objdump -d %t.ring0 --print-imm-hex | FileCheck %s --check-prefix=CHECK-BIN

# CHECK-RING0: BB Count : 1
# CHECK-RING3: BB Count : 2

# CHECK-BIN: <main>:
# CHECK-BIN-NEXT: f4 hlt
# CHECK-BIN-NEXT: c3 retq

.global main
.type main, %function
main:
hlt
retq
.size main, .-main
Loading