Skip to content

Commit

Permalink
[LongJumpPass] X86 enablement. First attempt.
Browse files Browse the repository at this point in the history
(cherry picked from FBD8753328)
  • Loading branch information
plotfi authored and maksfb committed Jul 6, 2018
1 parent b447979 commit 64c429d
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 3 deletions.
3 changes: 1 addition & 2 deletions bolt/src/BinaryPassManager.cpp
Expand Up @@ -460,8 +460,7 @@ void BinaryFunctionPassManager::runAllPasses(
// Thighten branches according to offset differences between branch and
// targets. No extra instructions after this pass, otherwise we may have
// relocations out of range and crash during linking.
if (BC.isAArch64())
Manager.registerPass(llvm::make_unique<LongJmpPass>(PrintLongJmp));
Manager.registerPass(llvm::make_unique<LongJmpPass>(PrintLongJmp));

// This pass turns tail calls into jumps which makes them invisible to
// function reordering. It's unsafe to use any CFG or instruction analysis
Expand Down
2 changes: 1 addition & 1 deletion bolt/src/Passes/LongJmp.cpp
Expand Up @@ -368,7 +368,7 @@ bool LongJmpPass::removeOrShrinkStubs(const BinaryContext &BC,
BinaryFunction &Func) {
bool Modified{false};

assert(BC.isAArch64() && "Unsupported arch");
assert((BC.isAArch64() || BC.isX86()) && "Unsupported arch");
constexpr auto InsnSize = 4; // AArch64
// Remove unnecessary stubs for branch targets we know we can fit in the
// instruction
Expand Down
95 changes: 95 additions & 0 deletions bolt/src/Target/X86/X86MCPlusBuilder.cpp
Expand Up @@ -2215,6 +2215,13 @@ class X86MCPlusBuilder : public MCPlusBuilder {
return true;
}

void createLongJmp(std::vector<MCInst> &Seq, const MCSymbol *Target,
MCContext *Ctx) const override {
MCInst Inst;
createUncondBranch(Inst, Target, Ctx);
Seq.emplace_back(Inst);
}

template <typename Itr>
std::pair<IndirectBranchType, MCInst *>
analyzePICJumpTable(Itr II,
Expand Down Expand Up @@ -2816,6 +2823,94 @@ class X86MCPlusBuilder : public MCPlusBuilder {
return true;
}

int getPCRelEncodingSize(MCInst &Inst) const override {

switch (Inst.getOpcode()) {
default:
llvm_unreachable("Failed to get pcrel encoding size");
return 0;

case X86::TAILJMPd: return 32;
case X86::TAILJMPm: return 32;

case X86::CALL64pcrel32: return 64;

case X86::JCXZ: return 8;
case X86::JECXZ: return 8;
case X86::JRCXZ: return 8;

case X86::JMP_1: return 8;
case X86::JMP_2: return 16;
case X86::JMP_4: return 32;

case X86::JE_1: return 8;
case X86::JE_2: return 16;
case X86::JE_4: return 32;
case X86::JNE_1: return 8;
case X86::JNE_2: return 16;
case X86::JNE_4: return 32;

case X86::JL_1: return 8;
case X86::JL_2: return 16;
case X86::JL_4: return 32;
case X86::JGE_1: return 8;
case X86::JGE_2: return 16;
case X86::JGE_4: return 32;

case X86::JLE_1: return 8;
case X86::JLE_2: return 16;
case X86::JLE_4: return 32;
case X86::JG_1: return 8;
case X86::JG_2: return 16;
case X86::JG_4: return 32;

case X86::JB_1: return 8;
case X86::JB_2: return 16;
case X86::JB_4: return 32;
case X86::JAE_1: return 8;
case X86::JAE_2: return 16;
case X86::JAE_4: return 32;

case X86::JBE_1: return 8;
case X86::JBE_2: return 16;
case X86::JBE_4: return 32;
case X86::JA_1: return 8;
case X86::JA_2: return 16;
case X86::JA_4: return 32;

case X86::JS_1: return 8;
case X86::JS_2: return 16;
case X86::JS_4: return 32;
case X86::JNS_1: return 8;
case X86::JNS_2: return 16;
case X86::JNS_4: return 32;

case X86::JP_1: return 8;
case X86::JP_2: return 16;
case X86::JP_4: return 32;
case X86::JNP_1: return 8;
case X86::JNP_2: return 16;
case X86::JNP_4: return 32;

case X86::JO_1: return 8;
case X86::JO_2: return 16;
case X86::JO_4: return 32;
case X86::JNO_1: return 8;
case X86::JNO_2: return 16;
case X86::JNO_4: return 32;
}
}

// TODO
int getShortJmpEncodingSize() const override {
return 16;
}

// TODO
int getUncondBranchEncodingSize() const override {
return 28;
}

unsigned getCanonicalBranchOpcode(unsigned Opcode) const override {
switch (Opcode) {
default:
Expand Down

0 comments on commit 64c429d

Please sign in to comment.