From: mortimer Date: Sun, 11 Jul 2021 20:32:00 +0000 (+0000) Subject: Optimize gadget fixups for MOV instructions. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=3ef334a888d8f6af03ca812b84b77826d6a22879;p=openbsd Optimize gadget fixups for MOV instructions. Instead of swapping registers around, we can just use the REV version of the same instruction, which has the same effect but encodes differently and does not result in return bytes in the binary. This reduces the number of xchg instructions resulting from gadget fixing. Prompted by ratchov@, with input from millert@ and sthen@. ok sthen@ --- diff --git a/gnu/llvm/llvm/lib/Target/X86/X86FixupGadgets.cpp b/gnu/llvm/llvm/lib/Target/X86/X86FixupGadgets.cpp index ea050ae7acb..6610d425b83 100644 --- a/gnu/llvm/llvm/lib/Target/X86/X86FixupGadgets.cpp +++ b/gnu/llvm/llvm/lib/Target/X86/X86FixupGadgets.cpp @@ -90,6 +90,7 @@ private: unsigned getEquivalentRegForReg(unsigned oreg, unsigned nreg) const; bool hasImplicitUseOrDef(const MachineInstr &MI, unsigned Reg1, unsigned Reg2) const; + bool fixupWithoutExchange(MachineInstr &MI); bool fixupInstruction(MachineFunction &MF, MachineBasicBlock &MBB, MachineInstr &MI, struct FixupInfo Info); @@ -563,6 +564,38 @@ bool FixupGadgetsPass::hasImplicitUseOrDef(const MachineInstr &MI, return false; } +bool FixupGadgetsPass::fixupWithoutExchange(MachineInstr &MI) { + switch (MI.getOpcode()) { + case X86::MOV8rr_REV: + MI.setDesc(TII->get(X86::MOV8rr)); + break; + case X86::MOV16rr_REV: + MI.setDesc(TII->get(X86::MOV16rr)); + break; + case X86::MOV32rr_REV: + MI.setDesc(TII->get(X86::MOV32rr)); + break; + case X86::MOV64rr_REV: + MI.setDesc(TII->get(X86::MOV64rr)); + break; + case X86::MOV8rr: + MI.setDesc(TII->get(X86::MOV8rr_REV)); + break; + case X86::MOV16rr: + MI.setDesc(TII->get(X86::MOV16rr_REV)); + break; + case X86::MOV32rr: + MI.setDesc(TII->get(X86::MOV32rr_REV)); + break; + case X86::MOV64rr: + MI.setDesc(TII->get(X86::MOV64rr_REV)); + break; + default: + return false; + } + return true; +} + bool FixupGadgetsPass::fixupInstruction(MachineFunction &MF, MachineBasicBlock &MBB, MachineInstr &MI, FixupInfo Info) { @@ -610,6 +643,11 @@ bool FixupGadgetsPass::fixupInstruction(MachineFunction &MF, SwapReg2 = treg; } + // Check for specific instructions we can fix without the xchg dance + if (fixupWithoutExchange(MI)) { + return true; + } + // Swap the two registers to start BuildMI(MBB, MI, DL, TII->get(XCHG)) .addReg(SwapReg1, RegState::Define)