aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/X86/X86WinFixupBufferSecurityCheck.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86/X86WinFixupBufferSecurityCheck.cpp')
-rw-r--r--llvm/lib/Target/X86/X86WinFixupBufferSecurityCheck.cpp245
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;
-}