diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86WinFixupBufferSecurityCheck.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86WinFixupBufferSecurityCheck.cpp | 245 |
1 files changed, 0 insertions, 245 deletions
diff --git a/llvm/lib/Target/X86/X86WinFixupBufferSecurityCheck.cpp b/llvm/lib/Target/X86/X86WinFixupBufferSecurityCheck.cpp deleted file mode 100644 index 5c12af1fee63..000000000000 --- a/llvm/lib/Target/X86/X86WinFixupBufferSecurityCheck.cpp +++ /dev/null @@ -1,245 +0,0 @@ -//===- X86WinFixupBufferSecurityCheck.cpp Fix Buffer Security Check Call -===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// Buffer Security Check implementation inserts windows specific callback into -// code. On windows, __security_check_cookie call gets call everytime function -// is return without fixup. Since this function is defined in runtime library, -// it incures cost of call in dll which simply does comparison and returns most -// time. With Fixup, We selective move to call in DLL only if comparison fails. -//===----------------------------------------------------------------------===// - -#include "X86.h" -#include "X86FrameLowering.h" -#include "X86InstrInfo.h" -#include "X86Subtarget.h" -#include "llvm/CodeGen/LivePhysRegs.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/IR/Module.h" - -using namespace llvm; - -#define DEBUG_TYPE "x86-win-fixup-bscheck" - -namespace { - -class X86WinFixupBufferSecurityCheckPass : public MachineFunctionPass { -public: - static char ID; - - X86WinFixupBufferSecurityCheckPass() : MachineFunctionPass(ID) {} - - StringRef getPassName() const override { - return "X86 Windows Fixup Buffer Security Check"; - } - - bool runOnMachineFunction(MachineFunction &MF) override; - - std::pair<MachineBasicBlock *, MachineInstr *> - getSecurityCheckerBasicBlock(MachineFunction &MF); - - void getGuardCheckSequence(MachineBasicBlock *CurMBB, MachineInstr *CheckCall, - MachineInstr *SeqMI[5]); - - void SplitBasicBlock(MachineBasicBlock *CurMBB, MachineBasicBlock *NewRetMBB, - MachineBasicBlock::iterator SplitIt); - - void FinishBlock(MachineBasicBlock *MBB); - - void FinishFunction(MachineBasicBlock *FailMBB, MachineBasicBlock *NewRetMBB); - - std::pair<MachineInstr *, MachineInstr *> - CreateFailCheckSequence(MachineBasicBlock *CurMBB, MachineBasicBlock *FailMBB, - MachineInstr *SeqMI[5]); -}; -} // end anonymous namespace - -char X86WinFixupBufferSecurityCheckPass::ID = 0; - -INITIALIZE_PASS(X86WinFixupBufferSecurityCheckPass, DEBUG_TYPE, DEBUG_TYPE, - false, false) - -FunctionPass *llvm::createX86WinFixupBufferSecurityCheckPass() { - return new X86WinFixupBufferSecurityCheckPass(); -} - -void X86WinFixupBufferSecurityCheckPass::SplitBasicBlock( - MachineBasicBlock *CurMBB, MachineBasicBlock *NewRetMBB, - MachineBasicBlock::iterator SplitIt) { - NewRetMBB->splice(NewRetMBB->end(), CurMBB, SplitIt, CurMBB->end()); -} - -std::pair<MachineBasicBlock *, MachineInstr *> -X86WinFixupBufferSecurityCheckPass::getSecurityCheckerBasicBlock( - MachineFunction &MF) { - MachineBasicBlock::reverse_iterator RBegin, REnd; - - for (auto &MBB : llvm::reverse(MF)) { - for (RBegin = MBB.rbegin(), REnd = MBB.rend(); RBegin != REnd; ++RBegin) { - auto &MI = *RBegin; - if (MI.getOpcode() == X86::CALL64pcrel32 && - MI.getNumExplicitOperands() == 1) { - auto MO = MI.getOperand(0); - if (MO.isGlobal()) { - auto Callee = dyn_cast<Function>(MO.getGlobal()); - if (Callee && Callee->getName() == "__security_check_cookie") { - return std::make_pair(&MBB, &MI); - break; - } - } - } - } - } - return std::make_pair(nullptr, nullptr); -} - -void X86WinFixupBufferSecurityCheckPass::getGuardCheckSequence( - MachineBasicBlock *CurMBB, MachineInstr *CheckCall, - MachineInstr *SeqMI[5]) { - - MachineBasicBlock::iterator UIt(CheckCall); - MachineBasicBlock::reverse_iterator DIt(CheckCall); - // Seq From StackUp to Stack Down Is fixed. - // ADJCALLSTACKUP64 - ++UIt; - SeqMI[4] = &*UIt; - - // CALL __security_check_cookie - SeqMI[3] = CheckCall; - - // COPY function slot cookie - ++DIt; - SeqMI[2] = &*DIt; - - // ADJCALLSTACKDOWN64 - ++DIt; - SeqMI[1] = &*DIt; - - MachineBasicBlock::reverse_iterator XIt(SeqMI[1]); - for (; XIt != CurMBB->rbegin(); ++XIt) { - auto &CI = *XIt; - if ((CI.getOpcode() == X86::XOR64_FP) || (CI.getOpcode() == X86::XOR32_FP)) - break; - } - SeqMI[0] = &*XIt; -} - -std::pair<MachineInstr *, MachineInstr *> -X86WinFixupBufferSecurityCheckPass::CreateFailCheckSequence( - MachineBasicBlock *CurMBB, MachineBasicBlock *FailMBB, - MachineInstr *SeqMI[5]) { - - auto MF = CurMBB->getParent(); - - Module &M = *MF->getFunction().getParent(); - GlobalVariable *GV = M.getGlobalVariable("__security_cookie"); - assert(GV && " Security Cookie was not installed!"); - - const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); - - MachineInstr *GuardXor = SeqMI[0]; - MachineBasicBlock::iterator InsertPt(GuardXor); - ++InsertPt; - - // Compare security_Cookie with XOR_Val, if not same, we have violation - auto CMI = BuildMI(*CurMBB, InsertPt, DebugLoc(), TII->get(X86::CMP64rm)) - .addReg(GuardXor->getOperand(0).getReg()) - .addReg(X86::RIP) - .addImm(1) - .addReg(X86::NoRegister) - .addGlobalAddress(GV) - .addReg(X86::NoRegister); - - BuildMI(*CurMBB, InsertPt, DebugLoc(), TII->get(X86::JCC_1)) - .addMBB(FailMBB) - .addImm(X86::COND_NE); - - auto JMI = BuildMI(*CurMBB, InsertPt, DebugLoc(), TII->get(X86::JMP_1)); - - return std::make_pair(CMI.getInstr(), JMI.getInstr()); -} - -void X86WinFixupBufferSecurityCheckPass::FinishBlock(MachineBasicBlock *MBB) { - LivePhysRegs LiveRegs; - computeAndAddLiveIns(LiveRegs, *MBB); -} - -void X86WinFixupBufferSecurityCheckPass::FinishFunction( - MachineBasicBlock *FailMBB, MachineBasicBlock *NewRetMBB) { - FailMBB->getParent()->RenumberBlocks(); - // FailMBB includes call to MSCV RT where is __security_check_cookie - // function is called. This function uses regcall and it expects cookie - // value from stack slot.( even if this is modified) - // Before going further we compute back livein for this block to make sure - // it is live and provided. - FinishBlock(FailMBB); - FinishBlock(NewRetMBB); -} - -bool X86WinFixupBufferSecurityCheckPass::runOnMachineFunction( - MachineFunction &MF) { - bool Changed = false; - const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>(); - - if (!(STI.isTargetWindowsItanium() || STI.isTargetWindowsMSVC())) - return Changed; - - // Check if security cookie was installed or not - Module &M = *MF.getFunction().getParent(); - GlobalVariable *GV = M.getGlobalVariable("__security_cookie"); - if (!GV) - return Changed; - - const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); - - // Check if security check cookie was installed or not - auto [CurMBB, CheckCall] = getSecurityCheckerBasicBlock(MF); - - if (!CheckCall) - return Changed; - - MachineBasicBlock *FailMBB = MF.CreateMachineBasicBlock(); - MachineBasicBlock *NewRetMBB = MF.CreateMachineBasicBlock(); - - MF.insert(MF.end(), NewRetMBB); - MF.insert(MF.end(), FailMBB); - - MachineInstr *SeqMI[5]; - getGuardCheckSequence(CurMBB, CheckCall, SeqMI); - // MachineInstr * GuardXor = SeqMI[0]; - - auto FailSeqRange = CreateFailCheckSequence(CurMBB, FailMBB, SeqMI); - MachineInstrBuilder JMI(MF, FailSeqRange.second); - - // After Inserting JMP_1, we can not have two terminators - // in same block, split CurrentMBB after JMP_1 - MachineBasicBlock::iterator SplitIt(SeqMI[4]); - ++SplitIt; - SplitBasicBlock(CurMBB, NewRetMBB, SplitIt); - - // Fill up Failure Routine, move Fail Check Squence from CurMBB to FailMBB - MachineBasicBlock::iterator U1It(SeqMI[1]); - MachineBasicBlock::iterator U2It(SeqMI[4]); - ++U2It; - FailMBB->splice(FailMBB->end(), CurMBB, U1It, U2It); - BuildMI(*FailMBB, FailMBB->end(), DebugLoc(), TII->get(X86::INT3)); - - // Move left over instruction after StackUp - // from Current Basic BLocks into New Return Block - JMI.addMBB(NewRetMBB); - MachineBasicBlock::iterator SplicePt(JMI.getInstr()); - ++SplicePt; - if (SplicePt != CurMBB->end()) - NewRetMBB->splice(NewRetMBB->end(), CurMBB, SplicePt); - - // Restructure Basic Blocks - CurMBB->addSuccessor(NewRetMBB); - CurMBB->addSuccessor(FailMBB); - - FinishFunction(FailMBB, NewRetMBB); - return !Changed; -} |
