[LongJumpPass] X86 enablement. First attempt.

(cherry picked from FBD8753328)
This commit is contained in:
Puyan Lotfi 2018-07-06 12:31:36 -07:00 committed by Maksim Panchenko
parent b447979b8c
commit 64c429da89
3 changed files with 97 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -2215,6 +2215,13 @@ public:
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,
@ -2816,6 +2823,94 @@ public:
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: