1//===-- X86ReturnProtectorLowering.cpp - ----------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the X86 implementation of ReturnProtectorLowering class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "X86ReturnProtectorLowering.h" 15#include "X86InstrBuilder.h" 16#include "X86InstrInfo.h" 17#include "X86MachineFunctionInfo.h" 18#include "X86Subtarget.h" 19#include "X86TargetMachine.h" 20#include "llvm/CodeGen/MachineFunction.h" 21#include "llvm/CodeGen/MachineInstrBuilder.h" 22#include "llvm/CodeGen/MachineModuleInfo.h" 23#include "llvm/CodeGen/MachineRegisterInfo.h" 24#include "llvm/IR/Function.h" 25#include "llvm/MC/MCAsmInfo.h" 26#include "llvm/MC/MCSymbol.h" 27#include "llvm/Support/Debug.h" 28#include "llvm/Target/TargetOptions.h" 29#include <cstdlib> 30 31using namespace llvm; 32 33void X86ReturnProtectorLowering::insertReturnProtectorPrologue( 34 MachineFunction &MF, MachineBasicBlock &MBB, GlobalVariable *cookie) const { 35 36 MachineBasicBlock::instr_iterator MI = MBB.instr_begin(); 37 DebugLoc MBBDL = MBB.findDebugLoc(MI); 38 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 39 unsigned REG = MF.getFrameInfo().getReturnProtectorRegister(); 40 41 BuildMI(MBB, MI, MBBDL, TII->get(X86::MOV64rm), REG) 42 .addReg(X86::RIP) 43 .addImm(0) 44 .addReg(0) 45 .addGlobalAddress(cookie) 46 .addReg(0); 47 addDirectMem(BuildMI(MBB, MI, MBBDL, TII->get(X86::XOR64rm), REG).addReg(REG), 48 X86::RSP); 49} 50 51void X86ReturnProtectorLowering::insertReturnProtectorEpilogue( 52 MachineFunction &MF, MachineInstr &MI, GlobalVariable *cookie) const { 53 54 MachineBasicBlock &MBB = *MI.getParent(); 55 DebugLoc MBBDL = MI.getDebugLoc(); 56 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 57 unsigned REG = MF.getFrameInfo().getReturnProtectorRegister(); 58 59 addDirectMem(BuildMI(MBB, MI, MBBDL, TII->get(X86::XOR64rm), REG).addReg(REG), 60 X86::RSP); 61 BuildMI(MBB, MI, MBBDL, TII->get(X86::CMP64rm)) 62 .addReg(REG) 63 .addReg(X86::RIP) 64 .addImm(0) 65 .addReg(0) 66 .addGlobalAddress(cookie) 67 .addReg(0); 68 BuildMI(MBB, MI, MBBDL, TII->get(X86::RETGUARD_JMP_TRAP)); 69} 70 71bool X86ReturnProtectorLowering::opcodeIsReturn(unsigned opcode) const { 72 switch (opcode) { 73 case X86::RET: 74 case X86::RET16: 75 case X86::RET32: 76 case X86::RET64: 77 case X86::RETI16: 78 case X86::RETI32: 79 case X86::RETI64: 80 case X86::LRET16: 81 case X86::LRET32: 82 case X86::LRET64: 83 case X86::LRETI16: 84 case X86::LRETI32: 85 case X86::LRETI64: 86 return true; 87 default: 88 return false; 89 } 90} 91 92void X86ReturnProtectorLowering::fillTempRegisters( 93 MachineFunction &MF, std::vector<unsigned> &TempRegs) const { 94 95 TempRegs.push_back(X86::R11); 96 TempRegs.push_back(X86::R10); 97 const Function &F = MF.getFunction(); 98 if (!F.isVarArg()) { 99 // We can use any of the caller saved unused arg registers 100 switch (F.arg_size()) { 101 case 0: 102 TempRegs.push_back(X86::RDI); 103 LLVM_FALLTHROUGH; 104 case 1: 105 TempRegs.push_back(X86::RSI); 106 LLVM_FALLTHROUGH; 107 case 2: // RDX is the 2nd return register 108 case 3: 109 TempRegs.push_back(X86::RCX); 110 LLVM_FALLTHROUGH; 111 case 4: 112 TempRegs.push_back(X86::R8); 113 LLVM_FALLTHROUGH; 114 case 5: 115 TempRegs.push_back(X86::R9); 116 LLVM_FALLTHROUGH; 117 default: 118 break; 119 } 120 } 121} 122