PPCReturnProtectorLowering.cpp revision 1.2
1//===-- PPCReturnProtectorLowering.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 PPC implementation of ReturnProtectorLowering 11// class. 12// 13//===----------------------------------------------------------------------===// 14 15#include "PPC.h" 16#include "PPCInstrInfo.h" 17#include "PPCMachineFunctionInfo.h" 18#include "PPCReturnProtectorLowering.h" 19#include "PPCTargetMachine.h" 20#include "llvm/CodeGen/MachineFrameInfo.h" 21#include "llvm/CodeGen/MachineFunction.h" 22#include "llvm/CodeGen/MachineInstrBuilder.h" 23#include "llvm/CodeGen/MachineModuleInfo.h" 24#include "llvm/CodeGen/MachineRegisterInfo.h" 25#include "llvm/IR/Function.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 PPCReturnProtectorLowering::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 const TargetMachine &TM = MF.getTarget(); 40 unsigned REG = MF.getFrameInfo().getReturnProtectorRegister(); 41 bool is64bit = MF.getSubtarget<PPCSubtarget>().isPPC64(); 42 bool isELFv2 = MF.getSubtarget<PPCSubtarget>().isELFv2ABI(); 43 44 unsigned LRReg = PPC::R0; 45 unsigned TOCReg = PPC::R2; 46 unsigned XOR = PPC::XOR; 47 unsigned LWZ = PPC::LWZ; 48 unsigned MFLR = PPC::MFLR; 49 if (is64bit) { 50 LRReg = PPC::X0; 51 TOCReg = PPC::X2; 52 XOR = PPC::XOR8; 53 LWZ = PPC::LWZ8; 54 MFLR = PPC::MFLR8; 55 } 56 57 if (!MBB.isLiveIn(LRReg)) 58 MBB.addLiveIn(LRReg); 59 60 if (is64bit) { 61 // PIC and non-PIC is the same 62 if (!isELFv2) 63 llvm_unreachable("ppc64 retguard requires ELFv2"); 64 // Get the return address into LRReg 65 BuildMI(MBB, MI, MBBDL, TII->get(MFLR), LRReg); 66 // Load the random cookie value into REG 67 BuildMI(MBB, MI, MBBDL, TII->get(PPC::ADDIStocHA8), REG) 68 .addReg(TOCReg) 69 .addGlobalAddress(cookie); 70 BuildMI(MBB, MI, MBBDL, TII->get(PPC::LD), REG) 71 .addGlobalAddress(cookie, 0, PPCII::MO_TOC_LO) 72 .addReg(REG); 73 // XOR cookie ^ random = retguard cookie 74 BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG) 75 .addReg(REG) 76 .addReg(LRReg); 77 } else { 78 // 32 bit 79 if (TM.isPositionIndependent()) { 80 MCSymbol *HereSym = MF.getContext().createTempSymbol(); 81 // Get LR into a register, and get PC into another register 82 BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_PC), REG) 83 .addReg(LRReg, RegState::Define) 84 .addSym(HereSym); 85 // Get the random cookie address into REG 86 BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_GOT), REG) 87 .addReg(REG) 88 .addSym(HereSym); 89 BuildMI(MBB, MI, MBBDL, TII->get(PPC::LWZtoc), REG) 90 .addGlobalAddress(cookie, 0, 0) 91 .addReg(REG); 92 // Now load the random cookie value 93 BuildMI(MBB, MI, MBBDL, TII->get(PPC::LWZ), REG) 94 .addImm(0) 95 .addReg(REG); 96 // XOR cookie ^ random = retguard cookie 97 BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG) 98 .addReg(REG) 99 .addReg(LRReg); 100 } else { 101 // Non-PIC prologue 102 // Load LR into a register 103 BuildMI(MBB, MI, MBBDL, TII->get(MFLR), LRReg); 104 // Load random cookie into another register 105 BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_COOKIE), REG) 106 .addGlobalAddress(cookie); 107 // XOR cookie ^ random = retguard cookie 108 BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG) 109 .addReg(REG) 110 .addReg(LRReg); 111 } 112 } 113} 114 115void PPCReturnProtectorLowering::insertReturnProtectorEpilogue( 116 MachineFunction &MF, MachineInstr &MI, GlobalVariable *cookie) const { 117 118 MachineBasicBlock &MBB = *MI.getParent(); 119 DebugLoc MBBDL = MI.getDebugLoc(); 120 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 121 const TargetMachine &TM = MF.getTarget(); 122 unsigned REG = MF.getFrameInfo().getReturnProtectorRegister(); 123 bool is64bit = MF.getSubtarget<PPCSubtarget>().isPPC64(); 124 bool isELFv2 = MF.getSubtarget<PPCSubtarget>().isELFv2ABI(); 125 126 unsigned LRReg = PPC::R0; 127 unsigned TOCReg = PPC::R2; 128 unsigned RGReg = PPC::R12; 129 unsigned TRAP = PPC::TW; 130 unsigned XOR = PPC::XOR; 131 unsigned LWZ = PPC::LWZ; 132 unsigned MFLR = PPC::MFLR; 133 if (is64bit) { 134 LRReg = PPC::X0; 135 TOCReg = PPC::X2; 136 RGReg = PPC::X12; 137 TRAP = PPC::TD; 138 XOR = PPC::XOR8; 139 LWZ = PPC::LWZ8; 140 MFLR = PPC::MFLR8; 141 } 142 143 if (!MBB.isLiveIn(LRReg)) 144 MBB.addLiveIn(LRReg); 145 if (!MBB.isLiveIn(RGReg)) 146 MBB.addLiveIn(RGReg); 147 148 if (is64bit) { 149 // PIC and non-PIC is the same 150 if (!isELFv2) 151 llvm_unreachable("ppc64 retguard requires ELFv2"); 152 // Get the return address into LRReg 153 BuildMI(MBB, MI, MBBDL, TII->get(MFLR), LRReg); 154 // XOR the LRReg with the retguard cookie value 155 BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG) 156 .addReg(REG) 157 .addReg(LRReg); 158 // Load the random cookie value into RGReg 159 BuildMI(MBB, MI, MBBDL, TII->get(PPC::ADDIStocHA8), RGReg) 160 .addReg(TOCReg) 161 .addGlobalAddress(cookie); 162 BuildMI(MBB, MI, MBBDL, TII->get(PPC::LD), RGReg) 163 .addGlobalAddress(cookie, 0, PPCII::MO_TOC_LO) 164 .addReg(RGReg); 165 // Trap if they don't compare 166 BuildMI(MBB, MI, MBBDL, TII->get(TRAP)) 167 .addImm(24) 168 .addReg(REG) 169 .addReg(RGReg); 170 } else { 171 // 32 bit 172 if (TM.isPositionIndependent()) { 173 // Get the PC into RGReg and the LR value into LRReg 174 MCSymbol *HereSym = MF.getContext().createTempSymbol(); 175 BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_PC), RGReg) 176 .addReg(LRReg, RegState::Define) 177 .addSym(HereSym); 178 // XOR the LRReg with the retguard cookie value 179 BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG) 180 .addReg(REG) 181 .addReg(LRReg); 182 // Get the random cookie address into RGReg 183 BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_GOT), RGReg) 184 .addReg(RGReg) 185 .addSym(HereSym); 186 BuildMI(MBB, MI, MBBDL, TII->get(PPC::LWZtoc), RGReg) 187 .addGlobalAddress(cookie, 0, 0) 188 .addReg(RGReg); 189 // Load the cookie random balue 190 BuildMI(MBB, MI, MBBDL, TII->get(PPC::LWZ), RGReg) 191 .addImm(0) 192 .addReg(RGReg); 193 // Trap if they don't compare 194 BuildMI(MBB, MI, MBBDL, TII->get(TRAP)) 195 .addImm(24) 196 .addReg(REG) 197 .addReg(RGReg); 198 } else { 199 // Get LR into a register 200 BuildMI(MBB, MI, MBBDL, TII->get(MFLR), LRReg); 201 // XOR the LR Reg with the retguard cookie value 202 BuildMI(MBB, MI, MBBDL, TII->get(XOR), REG) 203 .addReg(REG) 204 .addReg(LRReg); 205 BuildMI(MBB, MI, MBBDL, TII->get(PPC::RETGUARD_LOAD_COOKIE), RGReg) 206 .addGlobalAddress(cookie); 207 // Trap if they don't compare 208 BuildMI(MBB, MI, MBBDL, TII->get(TRAP)) 209 .addImm(24) 210 .addReg(REG) 211 .addReg(RGReg); 212 } 213 } 214} 215 216bool PPCReturnProtectorLowering::opcodeIsReturn(unsigned opcode) const { 217 switch (opcode) { 218 case PPC::BLR: 219 case PPC::BCCLR: 220 case PPC::BCLR: 221 case PPC::BCLRn: 222 case PPC::BDZLR: 223 case PPC::BDNZLR: 224 case PPC::BDZLRp: 225 case PPC::BDNZLRp: 226 case PPC::BDZLRm: 227 case PPC::BDNZLRm: 228 case PPC::BLR8: 229 case PPC::BDZLR8: 230 case PPC::BDNZLR8: 231 return true; 232 default: 233 return false; 234 } 235} 236 237void PPCReturnProtectorLowering::fillTempRegisters( 238 MachineFunction &MF, std::vector<unsigned> &TempRegs) const { 239 240 const Function &F = MF.getFunction(); 241 242 bool is64bit = MF.getSubtarget<PPCSubtarget>().isPPC64(); 243 244 // R0/R12 are also the hardcoded temp regs for the rest of 245 // frame lowering, so leave them alone. 246 //TempRegs.push_back(is64bit ? PPC::X0 : PPC::R0); 247 //TempRegs.push_back(is64bit ? PPC::X12 : PPC::R12); 248 // X11 is also the 'nest' param or environment pointer 249 TempRegs.push_back(is64bit ? PPC::X11 : PPC::R11); 250 251 if (!F.isVarArg()) { 252 // We can use any of the caller saved unused arg registers 253 switch (F.arg_size()) { 254 case 0: // X3/R3 are used to return 255 case 1: // X4/R4 are used to return 256 case 2: 257 TempRegs.push_back(is64bit ? PPC::X5 : PPC::R5); 258 LLVM_FALLTHROUGH; 259 case 3: 260 TempRegs.push_back(is64bit ? PPC::X6 : PPC::R6); 261 LLVM_FALLTHROUGH; 262 case 4: 263 TempRegs.push_back(is64bit ? PPC::X7 : PPC::R7); 264 LLVM_FALLTHROUGH; 265 case 5: 266 TempRegs.push_back(is64bit ? PPC::X8 : PPC::R8); 267 LLVM_FALLTHROUGH; 268 case 6: 269 TempRegs.push_back(is64bit ? PPC::X9 : PPC::R9); 270 LLVM_FALLTHROUGH; 271 case 7: 272 TempRegs.push_back(is64bit ? PPC::X10 : PPC::R10); 273 LLVM_FALLTHROUGH; 274 default: 275 break; 276 } 277 } 278} 279