1ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===-- ShadowStackGCLowering.cpp - Custom lowering for shadow-stack gc ---===// 2ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 3ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// The LLVM Compiler Infrastructure 4ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 5ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// This file is distributed under the University of Illinois Open Source 6ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// License. See LICENSE.TXT for details. 7ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 8ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 9ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// This file contains the custom lowering code required by the shadow-stack GC 11ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// strategy. 12ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// 13ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 14ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 15ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/CodeGen/Passes.h" 16ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/ADT/StringExtras.h" 17ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/CodeGen/GCStrategy.h" 18ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/CallSite.h" 19ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/IRBuilder.h" 20ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/IntrinsicInst.h" 21ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/Module.h" 22ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 23ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesusing namespace llvm; 24ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 25ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#define DEBUG_TYPE "shadowstackgclowering" 26ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 27ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace { 28ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 29ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass ShadowStackGCLowering : public FunctionPass { 30ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// RootChain - This is the global linked-list that contains the chain of GC 31ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// roots. 32ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GlobalVariable *Head; 33ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 34ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// StackEntryTy - Abstract type of a link in the shadow stack. 35ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// 36ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StructType *StackEntryTy; 37ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StructType *FrameMapTy; 38ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 39ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// Roots - GC roots in the current function. Each is a pair of the 40ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// intrinsic call and its corresponding alloca. 41ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<std::pair<CallInst *, AllocaInst *>> Roots; 42ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 43ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 44ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines static char ID; 45ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ShadowStackGCLowering(); 46ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 47ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool doInitialization(Module &M) override; 48ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool runOnFunction(Function &F) override; 49ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 50ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesprivate: 51ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool IsNullValue(Value *V); 52ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant *GetFrameMap(Function &F); 53ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Type *GetConcreteStackEntryType(Function &F); 54ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void CollectRoots(Function &F); 55ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines static GetElementPtrInst *CreateGEP(LLVMContext &Context, IRBuilder<> &B, 564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Type *Ty, Value *BasePtr, int Idx1, 57ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const char *Name); 58ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines static GetElementPtrInst *CreateGEP(LLVMContext &Context, IRBuilder<> &B, 594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Type *Ty, Value *BasePtr, int Idx1, int Idx2, 60ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const char *Name); 61ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 62ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 64ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_BEGIN(ShadowStackGCLowering, "shadow-stack-gc-lowering", 65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "Shadow Stack GC Lowering", false, false) 66ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_DEPENDENCY(GCModuleInfo) 67ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_END(ShadowStackGCLowering, "shadow-stack-gc-lowering", 68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "Shadow Stack GC Lowering", false, false) 69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 70ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesFunctionPass *llvm::createShadowStackGCLoweringPass() { return new ShadowStackGCLowering(); } 71ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hineschar ShadowStackGCLowering::ID = 0; 73ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 74ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesShadowStackGCLowering::ShadowStackGCLowering() 75ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : FunctionPass(ID), Head(nullptr), StackEntryTy(nullptr), 76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FrameMapTy(nullptr) { 77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines initializeShadowStackGCLoweringPass(*PassRegistry::getPassRegistry()); 78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace { 81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// EscapeEnumerator - This is a little algorithm to find all escape points 82ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// from a function so that "finally"-style code can be inserted. In addition 83ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// to finding the existing return and unwind instructions, it also (if 84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// necessary) transforms any call instructions into invokes and sends them to 85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// a landing pad. 86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// It's wrapped up in a state machine using the same transform C# uses for 88ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 'yield return' enumerators, This transform allows it to be non-allocating. 89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesclass EscapeEnumerator { 90ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function &F; 91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const char *CleanupBBName; 92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // State. 94ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int State; 95ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function::iterator StateBB, StateE; 96ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> Builder; 97ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinespublic: 99ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EscapeEnumerator(Function &F, const char *N = "cleanup") 100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines : F(F), CleanupBBName(N), State(0), Builder(F.getContext()) {} 101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> *Next() { 103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines switch (State) { 104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines default: 105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case 0: 108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StateBB = F.begin(); 109ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StateE = F.end(); 110ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines State = 1; 111ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 112ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case 1: 113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Find all 'return', 'resume', and 'unwind' instructions. 114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (StateBB != StateE) { 115cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar BasicBlock *CurBB = &*StateBB++; 116ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Branches and invokes do not escape, only unwind, resume, and return 118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // do. 119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TerminatorInst *TI = CurBB->getTerminator(); 120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!isa<ReturnInst>(TI) && !isa<ResumeInst>(TI)) 121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 122ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 123cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Builder.SetInsertPoint(TI); 124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return &Builder; 125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines State = 2; 128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Find all 'call' instructions. 130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVector<Instruction *, 16> Calls; 131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (BasicBlock::iterator II = BB->begin(), EE = BB->end(); II != EE; 133ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ++II) 134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CallInst *CI = dyn_cast<CallInst>(II)) 135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!CI->getCalledFunction() || 136ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines !CI->getCalledFunction()->getIntrinsicID()) 137ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Calls.push_back(CI); 138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 139ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Calls.empty()) 140ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 142ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Create a cleanup block. 143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LLVMContext &C = F.getContext(); 144ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *CleanupBB = BasicBlock::Create(C, CleanupBBName, &F); 145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Type *ExnTy = 146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StructType::get(Type::getInt8PtrTy(C), Type::getInt32Ty(C), nullptr); 147cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!F.hasPersonalityFn()) { 148cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Constant *PersFn = F.getParent()->getOrInsertFunction( 149cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar "__gcc_personality_v0", 150cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar FunctionType::get(Type::getInt32Ty(C), true)); 151cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar F.setPersonalityFn(PersFn); 152cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LandingPadInst *LPad = 154cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar LandingPadInst::Create(ExnTy, 1, "cleanup.lpad", CleanupBB); 155ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LPad->setCleanup(true); 156ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ResumeInst *RI = ResumeInst::Create(LPad, CleanupBB); 157ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 158ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Transform the 'call' instructions into 'invoke's branching to the 159ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // cleanup block. Go in reverse order to make prettier BB names. 160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVector<Value *, 16> Args; 161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned I = Calls.size(); I != 0;) { 162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CallInst *CI = cast<CallInst>(Calls[--I]); 163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 164ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Split the basic block containing the function call. 165ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *CallBB = CI->getParent(); 166cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar BasicBlock *NewBB = CallBB->splitBasicBlock( 167cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar CI->getIterator(), CallBB->getName() + ".cont"); 168ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Remove the unconditional branch inserted at the end of CallBB. 170ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CallBB->getInstList().pop_back(); 171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NewBB->getInstList().remove(CI); 172ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 173ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Create a new invoke instruction. 174ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Args.clear(); 175ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CallSite CS(CI); 176ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Args.append(CS.arg_begin(), CS.arg_end()); 177ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 178ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines InvokeInst *II = 179ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines InvokeInst::Create(CI->getCalledValue(), NewBB, CleanupBB, Args, 180ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CI->getName(), CallBB); 181ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines II->setCallingConv(CI->getCallingConv()); 182ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines II->setAttributes(CI->getAttributes()); 183ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CI->replaceAllUsesWith(II); 184ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines delete CI; 185ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 186ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 187cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Builder.SetInsertPoint(RI); 188ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return &Builder; 189ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 190ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 191ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}; 192ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 193ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 194ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 195ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesConstant *ShadowStackGCLowering::GetFrameMap(Function &F) { 196ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // doInitialization creates the abstract type of this value. 197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Type *VoidPtr = Type::getInt8PtrTy(F.getContext()); 198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Truncate the ShadowStackDescriptor if some metadata is null. 200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned NumMeta = 0; 201ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVector<Constant *, 16> Metadata; 202ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned I = 0; I != Roots.size(); ++I) { 203ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant *C = cast<Constant>(Roots[I].first->getArgOperand(1)); 204ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!C->isNullValue()) 205ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NumMeta = I + 1; 206ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Metadata.push_back(ConstantExpr::getBitCast(C, VoidPtr)); 207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 208ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Metadata.resize(NumMeta); 209ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 210ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Type *Int32Ty = Type::getInt32Ty(F.getContext()); 211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 212ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant *BaseElts[] = { 213ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(Int32Ty, Roots.size(), false), 214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(Int32Ty, NumMeta, false), 215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines }; 216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 217ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant *DescriptorElts[] = { 218ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantStruct::get(FrameMapTy, BaseElts), 219ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantArray::get(ArrayType::get(VoidPtr, NumMeta), Metadata)}; 220ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 221ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Type *EltTys[] = {DescriptorElts[0]->getType(), DescriptorElts[1]->getType()}; 222ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StructType *STy = StructType::create(EltTys, "gc_map." + utostr(NumMeta)); 223ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 224ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant *FrameMap = ConstantStruct::get(STy, DescriptorElts); 225ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 226ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // FIXME: Is this actually dangerous as WritingAnLLVMPass.html claims? Seems 227ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // that, short of multithreaded LLVM, it should be safe; all that is 228ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // necessary is that a simple Module::iterator loop not be invalidated. 229ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Appending to the GlobalVariable list is safe in that sense. 230ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 231ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // All of the output passes emit globals last. The ExecutionEngine 232ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // explicitly supports adding globals to the module after 233ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // initialization. 234ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 235ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Still, if it isn't deemed acceptable, then this transformation needs 236ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // to be a ModulePass (which means it cannot be in the 'llc' pipeline 237ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // (which uses a FunctionPassManager (which segfaults (not asserts) if 238ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // provided a ModulePass))). 239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant *GV = new GlobalVariable(*F.getParent(), FrameMap->getType(), true, 240ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GlobalVariable::InternalLinkage, FrameMap, 241ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "__gc_" + F.getName()); 242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant *GEPIndices[2] = { 244ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(Type::getInt32Ty(F.getContext()), 0), 245ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(Type::getInt32Ty(F.getContext()), 0)}; 2460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar return ConstantExpr::getGetElementPtr(FrameMap->getType(), GV, GEPIndices); 247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 249ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesType *ShadowStackGCLowering::GetConcreteStackEntryType(Function &F) { 250ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // doInitialization creates the generic version of this type. 251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<Type *> EltTys; 252ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EltTys.push_back(StackEntryTy); 253ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (size_t I = 0; I != Roots.size(); I++) 254ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EltTys.push_back(Roots[I].second->getAllocatedType()); 255ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar return StructType::create(EltTys, ("gc_stackentry." + F.getName()).str()); 257ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 258ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 259ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// doInitialization - If this module uses the GC intrinsics, find them now. If 260ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// not, exit fast. 261ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ShadowStackGCLowering::doInitialization(Module &M) { 262ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool Active = false; 263ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Function &F : M) { 264ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (F.hasGC() && F.getGC() == std::string("shadow-stack")) { 265ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Active = true; 266ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 267ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 268ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 269ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Active) 270ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 271ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 272ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // struct FrameMap { 273ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // int32_t NumRoots; // Number of roots in stack frame. 274ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // int32_t NumMeta; // Number of metadata descriptors. May be < NumRoots. 275ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *Meta[]; // May be absent for roots without metadata. 276ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // }; 277ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::vector<Type *> EltTys; 278ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 32 bits is ok up to a 32GB stack frame. :) 279ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EltTys.push_back(Type::getInt32Ty(M.getContext())); 280ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Specifies length of variable length array. 281ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EltTys.push_back(Type::getInt32Ty(M.getContext())); 282ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines FrameMapTy = StructType::create(EltTys, "gc_map"); 283ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PointerType *FrameMapPtrTy = PointerType::getUnqual(FrameMapTy); 284ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 285ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // struct StackEntry { 286ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ShadowStackEntry *Next; // Caller's stack entry. 287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // FrameMap *Map; // Pointer to constant FrameMap. 288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // void *Roots[]; // Stack roots (in-place array, so we pretend). 289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // }; 290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StackEntryTy = StructType::create(M.getContext(), "gc_stackentry"); 292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EltTys.clear(); 294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EltTys.push_back(PointerType::getUnqual(StackEntryTy)); 295ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EltTys.push_back(FrameMapPtrTy); 296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StackEntryTy->setBody(EltTys); 297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PointerType *StackEntryPtrTy = PointerType::getUnqual(StackEntryTy); 298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Get the root chain if it already exists. 300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Head = M.getGlobalVariable("llvm_gc_root_chain"); 301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Head) { 302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If the root chain does not exist, insert a new one with linkonce 303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // linkage! 304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Head = new GlobalVariable( 305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines M, StackEntryPtrTy, false, GlobalValue::LinkOnceAnyLinkage, 306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant::getNullValue(StackEntryPtrTy), "llvm_gc_root_chain"); 307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else if (Head->hasExternalLinkage() && Head->isDeclaration()) { 308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Head->setInitializer(Constant::getNullValue(StackEntryPtrTy)); 309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Head->setLinkage(GlobalValue::LinkOnceAnyLinkage); 310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ShadowStackGCLowering::IsNullValue(Value *V) { 316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Constant *C = dyn_cast<Constant>(V)) 317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return C->isNullValue(); 318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid ShadowStackGCLowering::CollectRoots(Function &F) { 322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // FIXME: Account for original alignment. Could fragment the root array. 323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Approach 1: Null initialize empty slots at runtime. Yuck. 324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Approach 2: Emit a map of the array instead of just a count. 325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(Roots.empty() && "Not cleaned up?"); 327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVector<std::pair<CallInst *, AllocaInst *>, 16> MetaRoots; 329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 330ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) 332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++)) 333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Function *F = CI->getCalledFunction()) 334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (F->getIntrinsicID() == Intrinsic::gcroot) { 335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::pair<CallInst *, AllocaInst *> Pair = std::make_pair( 336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CI, 337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts())); 338ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (IsNullValue(CI->getArgOperand(1))) 339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Roots.push_back(Pair); 340ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else 341ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MetaRoots.push_back(Pair); 342ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 343ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 344ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Number roots with metadata (usually empty) at the beginning, so that the 345ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // FrameMap::Meta array can be elided. 346ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Roots.insert(Roots.begin(), MetaRoots.begin(), MetaRoots.end()); 347ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 349ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesGetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context, 3504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRBuilder<> &B, Type *Ty, 3514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *BasePtr, int Idx, 3524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar int Idx2, 3534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const char *Name) { 354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Indices[] = {ConstantInt::get(Type::getInt32Ty(Context), 0), 355ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(Type::getInt32Ty(Context), Idx), 356ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(Type::getInt32Ty(Context), Idx2)}; 3574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Val = B.CreateGEP(Ty, BasePtr, Indices, Name); 358ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 359ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(isa<GetElementPtrInst>(Val) && "Unexpected folded constant"); 360ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 361ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return dyn_cast<GetElementPtrInst>(Val); 362ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 363ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 364ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesGetElementPtrInst *ShadowStackGCLowering::CreateGEP(LLVMContext &Context, 3654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar IRBuilder<> &B, Type *Ty, Value *BasePtr, 366ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines int Idx, const char *Name) { 367ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *Indices[] = {ConstantInt::get(Type::getInt32Ty(Context), 0), 368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ConstantInt::get(Type::getInt32Ty(Context), Idx)}; 3694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *Val = B.CreateGEP(Ty, BasePtr, Indices, Name); 370ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 371ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines assert(isa<GetElementPtrInst>(Val) && "Unexpected folded constant"); 372ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 373ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return dyn_cast<GetElementPtrInst>(Val); 374ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 376ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// runOnFunction - Insert code to maintain the shadow stack. 377ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ShadowStackGCLowering::runOnFunction(Function &F) { 378ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Quick exit for functions that do not use the shadow stack GC. 379ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!F.hasGC() || 380ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines F.getGC() != std::string("shadow-stack")) 381ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 382ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 383ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LLVMContext &Context = F.getContext(); 384ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 385ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Find calls to llvm.gcroot. 386ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CollectRoots(F); 387ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 388ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If there are no roots in this function, then there is no need to add a 389ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // stack map entry for it. 390ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Roots.empty()) 391ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 392ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 393ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Build the constant map and figure the type of the shadow stack entry. 394ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *FrameMap = GetFrameMap(F); 395ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Type *ConcreteStackEntryTy = GetConcreteStackEntryType(F); 396ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 397ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Build the shadow stack entry at the very start of the function. 398ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock::iterator IP = F.getEntryBlock().begin(); 399ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines IRBuilder<> AtEntry(IP->getParent(), IP); 400ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 401ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *StackEntry = 402ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AtEntry.CreateAlloca(ConcreteStackEntryTy, nullptr, "gc_frame"); 403ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 404ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (isa<AllocaInst>(IP)) 405ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ++IP; 406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AtEntry.SetInsertPoint(IP->getParent(), IP); 407ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 408ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Initialize the map pointer and load the current head of the shadow stack. 409ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *CurrentHead = AtEntry.CreateLoad(Head, "gc_currhead"); 4104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Instruction *EntryMapPtr = CreateGEP(Context, AtEntry, ConcreteStackEntryTy, 4114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StackEntry, 0, 1, "gc_frame.map"); 412ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AtEntry.CreateStore(FrameMap, EntryMapPtr); 413ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 414ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // After all the allocas... 415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned I = 0, E = Roots.size(); I != E; ++I) { 416ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // For each root, find the corresponding slot in the aggregate... 4174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Value *SlotPtr = CreateGEP(Context, AtEntry, ConcreteStackEntryTy, 4184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StackEntry, 1 + I, "gc_root"); 419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 420ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // And use it in lieu of the alloca. 421ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AllocaInst *OriginalAlloca = Roots[I].second; 422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SlotPtr->takeName(OriginalAlloca); 423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OriginalAlloca->replaceAllUsesWith(SlotPtr); 424ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Move past the original stores inserted by GCStrategy::InitRoots. This isn't 427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // really necessary (the collector would never see the intermediate state at 428ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // runtime), but it's nicer not to push the half-initialized entry onto the 429ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // shadow stack. 430ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (isa<StoreInst>(IP)) 431ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ++IP; 432ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AtEntry.SetInsertPoint(IP->getParent(), IP); 433ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 434ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Push the entry onto the shadow stack. 4354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Instruction *EntryNextPtr = CreateGEP(Context, AtEntry, ConcreteStackEntryTy, 4364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StackEntry, 0, 0, "gc_frame.next"); 4374c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Instruction *NewHeadVal = CreateGEP(Context, AtEntry, ConcreteStackEntryTy, 4384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StackEntry, 0, "gc_newhead"); 439ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AtEntry.CreateStore(CurrentHead, EntryNextPtr); 440ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AtEntry.CreateStore(NewHeadVal, Head); 441ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 442ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // For each instruction that escapes... 443ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EscapeEnumerator EE(F, "gc_cleanup"); 444ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (IRBuilder<> *AtExit = EE.Next()) { 445ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Pop the entry from the shadow stack. Don't reuse CurrentHead from 446ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // AtEntry, since that would make the value live for the entire function. 447ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *EntryNextPtr2 = 4484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CreateGEP(Context, *AtExit, ConcreteStackEntryTy, StackEntry, 0, 0, 4494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "gc_frame.next"); 450ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *SavedHead = AtExit->CreateLoad(EntryNextPtr2, "gc_savedhead"); 451ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AtExit->CreateStore(SavedHead, Head); 452ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 453ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 454ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Delete the original allocas (which are no longer used) and the intrinsic 455ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // calls (which are no longer valid). Doing this last avoids invalidating 456ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // iterators. 457ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned I = 0, E = Roots.size(); I != E; ++I) { 458ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Roots[I].first->eraseFromParent(); 459ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Roots[I].second->eraseFromParent(); 460ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 461ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 462ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Roots.clear(); 463ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 464ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 465