BOLT: Add ud2 after indirect tailcalls.

Summary:
Insert ud2 instructions after indirect tailcalls to prevent the CPU from
decoding instructions following the callsite.

A simple counter in the peephole pass shows 3260 tail call traps inserted.

(cherry picked from FBD3859737)
This commit is contained in:
Bill Nell 2016-09-13 15:16:11 -07:00 committed by Maksim Panchenko
parent 2f1341b51d
commit ecc4b9e713
2 changed files with 28 additions and 0 deletions

View File

@ -1087,6 +1087,20 @@ void Peepholes::fixDoubleJumps(BinaryContext &BC,
}
}
void Peepholes::addTailcallTraps(BinaryContext &BC,
BinaryFunction &Function) {
for (auto &BB : Function) {
auto *Inst = BB.findLastNonPseudoInstruction();
if (Inst && BC.MIA->isTailCall(*Inst) && BC.MIA->isIndirectBranch(*Inst)) {
MCInst Trap;
if (BC.MIA->createTrap(Trap)) {
BB.addInstruction(Trap);
++TailCallTraps;
}
}
}
}
void Peepholes::runOnFunctions(BinaryContext &BC,
std::map<uint64_t, BinaryFunction> &BFs,
std::set<uint64_t> &LargeFunctions) {
@ -1095,9 +1109,11 @@ void Peepholes::runOnFunctions(BinaryContext &BC,
if (shouldOptimize(Function)) {
shortenInstructions(BC, Function);
fixDoubleJumps(BC, Function);
addTailcallTraps(BC, Function);
}
}
outs() << "BOLT-INFO: " << NumDoubleJumps << " double jumps patched.\n";
outs() << "BOLT-INFO: " << TailCallTraps << " tail call traps inserted.\n";
}
bool SimplifyRODataLoads::simplifyRODataLoads(

View File

@ -257,8 +257,20 @@ class SimplifyConditionalTailCalls : public BinaryFunctionPass {
/// Perform simple peephole optimizations.
class Peepholes : public BinaryFunctionPass {
uint64_t NumDoubleJumps{0};
uint64_t TailCallTraps{0};
/// Attempt to use the minimum operand width for arithmetic, branch and
/// move instructions.
void shortenInstructions(BinaryContext &BC, BinaryFunction &Function);
/// Replace double jumps with a jump directly to the target, i.e.
/// jmp/jcc L1; L1: jmp L2 -> jmp/jcc L2.
void fixDoubleJumps(BinaryContext &BC, BinaryFunction &Function);
/// Add trap instructions immediately after indirect tail calls to prevent
/// the processor from decoding instructions immediate following the
/// tailcall.
void addTailcallTraps(BinaryContext &BC, BinaryFunction &Function);
public:
explicit Peepholes(const cl::opt<bool> &PrintPass)
: BinaryFunctionPass(PrintPass) { }