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
31 using namespace llvm;
32
insertReturnProtectorPrologue(MachineFunction & MF,MachineBasicBlock & MBB,GlobalVariable * cookie) const33 void 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
insertReturnProtectorEpilogue(MachineFunction & MF,MachineInstr & MI,GlobalVariable * cookie) const51 void 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
opcodeIsReturn(unsigned opcode) const71 bool 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
fillTempRegisters(MachineFunction & MF,std::vector<unsigned> & TempRegs) const92 void 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