Lines Matching +full:actions +full:- +full:builder

1 //===-- X86WinEHState - Insert EH state updates for win32 exceptions ------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 // object is linked into a thread-local chain of registrations stored at fs:00.
14 //===----------------------------------------------------------------------===//
56 return "Windows 32-bit x86 EH state insertion";
62 void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
63 void unlinkExceptionRegistration(IRBuilder<> &Builder);
67 Value *emitEHLSDA(IRBuilder<> &Builder, Function *F);
72 void rewriteSetJmpCall(IRBuilder<> &Builder, Function &F, CallBase &Call,
81 // Module-level type getters.
86 // Per-module data.
94 // Per-function state
124 INITIALIZE_PASS(WinEHStatePass, "x86-winehstate",
161 PersonalityFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
168 // Skip this function if there are no EH pads and we aren't using IR-level
180 Type *Int8PtrType = PointerType::getUnqual(TheModule->getContext());
181 SetJmp3 = TheModule->getOrInsertFunction(
183 Type::getInt32Ty(TheModule->getContext()),
184 {Int8PtrType, Type::getInt32Ty(TheModule->getContext())},
198 // Reset per-function state.
219 LLVMContext &Context = TheModule->getContext();
237 LLVMContext &Context = TheModule->getContext();
259 LLVMContext &Context = TheModule->getContext();
279 IRBuilder<> Builder(&F->getEntryBlock(), F->getEntryBlock().begin());
280 Type *Int8PtrType = Builder.getPtrTy();
281 Type *Int32Ty = Builder.getInt32Ty();
282 Type *VoidTy = Builder.getVoidTy();
286 RegNode = Builder.CreateAlloca(RegNodeTy);
288 Value *SP = Builder.CreateStackSave();
289 Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
290 // TryLevel = -1
292 ParentBaseState = -1;
293 insertStateNumberStore(&*Builder.GetInsertPoint(), ParentBaseState);
296 Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 1);
297 linkExceptionRegistration(Builder, Trampoline);
299 CxxLongjmpUnwind = TheModule->getOrInsertFunction(
302 cast<Function>(CxxLongjmpUnwind.getCallee()->stripPointerCasts())
303 ->setCallingConv(CallingConv::X86_StdCall);
307 StringRef PersonalityName = PersonalityFn->getName();
312 RegNode = Builder.CreateAlloca(RegNodeTy);
314 EHGuardNode = Builder.CreateAlloca(Int32Ty);
317 Value *SP = Builder.CreateStackSave();
318 Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
319 // TryLevel = -2 / -1
321 ParentBaseState = UseStackGuard ? -2 : -1;
322 insertStateNumberStore(&*Builder.GetInsertPoint(), ParentBaseState);
324 Value *LSDA = emitEHLSDA(Builder, F);
325 LSDA = Builder.CreatePtrToInt(LSDA, Int32Ty);
329 Cookie = TheModule->getOrInsertGlobal("__security_cookie", Int32Ty);
330 Value *Val = Builder.CreateLoad(Int32Ty, Cookie, "cookie");
331 LSDA = Builder.CreateXor(LSDA, Val);
333 Builder.CreateStore(LSDA, Builder.CreateStructGEP(RegNodeTy, RegNode, 3));
337 Value *Val = Builder.CreateLoad(Int32Ty, Cookie);
338 Value *FrameAddr = Builder.CreateIntrinsic(
340 Builder.getPtrTy(TheModule->getDataLayout().getAllocaAddrSpace()),
341 Builder.getInt32(0), /*FMFSource=*/nullptr, "frameaddr");
342 Value *FrameAddrI32 = Builder.CreatePtrToInt(FrameAddr, Int32Ty);
343 FrameAddrI32 = Builder.CreateXor(FrameAddrI32, Val);
344 Builder.CreateStore(FrameAddrI32, EHGuardNode);
348 Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 2);
349 linkExceptionRegistration(Builder, PersonalityFn);
351 SehLongjmpUnwind = TheModule->getOrInsertFunction(
353 FunctionType::get(Type::getVoidTy(TheModule->getContext()), Int8PtrType,
355 cast<Function>(SehLongjmpUnwind.getCallee()->stripPointerCasts())
356 ->setCallingConv(CallingConv::X86_StdCall);
367 // If there is a musttail call, that's the de-facto terminator.
371 Builder.SetInsertPoint(T);
372 unlinkExceptionRegistration(Builder);
376 Value *WinEHStatePass::emitEHLSDA(IRBuilder<> &Builder, Function *F) {
377 return Builder.CreateIntrinsic(Intrinsic::x86_seh_lsda, {}, F);
388 LLVMContext &Context = ParentFunc->getContext();
402 GlobalValue::dropLLVMManglingEscape(ParentFunc->getName()),
404 if (auto *C = ParentFunc->getComdat())
405 Trampoline->setComdat(C);
407 IRBuilder<> Builder(EntryBB);
408 Value *LSDA = emitEHLSDA(Builder, ParentFunc);
409 auto AI = Trampoline->arg_begin();
411 CallInst *Call = Builder.CreateCall(TargetFuncTy, PersonalityFn, Args);
413 Call->setTailCall(true);
415 Call->addParamAttr(0, Attribute::InReg);
416 Builder.CreateRet(Call);
420 void WinEHStatePass::linkExceptionRegistration(IRBuilder<> &Builder,
423 Handler->addFnAttr("safeseh");
425 LLVMContext &C = Builder.getContext();
428 Builder.CreateStore(Handler, Builder.CreateStructGEP(LinkTy, Link, 1));
431 Value *Next = Builder.CreateLoad(PointerType::getUnqual(C), FSZero);
432 Builder.CreateStore(Next, Builder.CreateStructGEP(LinkTy, Link, 0));
434 Builder.CreateStore(Link, FSZero);
437 void WinEHStatePass::unlinkExceptionRegistration(IRBuilder<> &Builder) {
440 GEP = cast<GetElementPtrInst>(GEP->clone());
441 Builder.Insert(GEP);
445 LLVMContext &C = Builder.getContext();
447 // [fs:00] = Link->Next
448 Value *Next = Builder.CreateLoad(PointerType::getUnqual(C),
449 Builder.CreateStructGEP(LinkTy, Link, 0));
451 Builder.CreateStore(Next, FSZero);
456 // specific parameters to indicate how to restore the personality-specific frame
458 void WinEHStatePass::rewriteSetJmpCall(IRBuilder<> &Builder, Function &F,
471 OptionalArgs.push_back(emitEHLSDA(Builder, &F));
483 Builder.CreateBitCast(Call.getArgOperand(0), Builder.getPtrTy()));
484 Args.push_back(Builder.getInt32(OptionalArgs.size()));
489 CallInst *NewCI = Builder.CreateCall(SetJmp3, Args, OpBundles);
490 NewCI->setTailCallKind(CI->getTailCallKind());
494 NewCall = Builder.CreateInvoke(SetJmp3, II->getNormalDest(),
495 II->getUnwindDest(), Args, OpBundles);
497 NewCall->setCallingConv(Call.getCallingConv());
498 NewCall->setAttributes(Call.getAttributes());
499 NewCall->setDebugLoc(Call.getDebugLoc());
501 NewCall->takeName(&Call);
513 assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
516 dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHIIt())) {
519 BaseState = BaseStateI->second;
527 return CF && CF->isIntrinsic() && CF->getIntrinsicID() == ID;
538 // Calculate the state a call-site is in.
544 return getBaseStateForBB(BlockColors, FuncInfo, II->getNormalDest());
551 // Possibly throwing call instructions have no actions to take after
552 // an unwind. Ensure they are in the -1 state.
566 if (BB->isEHPad())
579 if (isa<CatchReturnInst>(PredBB->getTerminator()))
582 int PredState = PredEndState->second;
603 if (isa<CatchReturnInst>(BB->getTerminator()))
615 if (SuccBB->isEHPad())
618 int SuccState = SuccStartState->second;
650 IRBuilder<> Builder(RegNode->getNextNode());
651 Value *RegNodeI8 = Builder.CreateBitCast(RegNode, Builder.getPtrTy());
652 Builder.CreateIntrinsic(Intrinsic::x86_seh_ehregnode, {}, {RegNodeI8});
655 IRBuilder<> Builder(EHGuardNode->getNextNode());
657 Builder.CreateBitCast(EHGuardNode, Builder.getPtrTy());
658 Builder.CreateIntrinsic(Intrinsic::x86_seh_ehguard, {}, {EHGuardNodeI8});
671 // InitialStates yields the state of the first call-site for a BasicBlock.
673 // FinalStates yields the state of the last call-site for a BasicBlock.
676 // Initial/Final-States.
678 // Fill in InitialStates and FinalStates for BasicBlocks with call-sites.
694 // No call-sites in this basic block? That's OK, we will come back to these
700 LLVM_DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
702 LLVM_DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
708 // Try to fill-in InitialStates and FinalStates which have no call-sites.
739 // Finally, insert state stores before call-sites which transition us to a new
744 if (isa<CleanupPadInst>(FuncletEntryBB->getFirstNonPHIIt()))
748 LLVM_DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
765 if (EndState->second != PrevState)
766 insertStateNumberStore(BB->getTerminator(), EndState->second);
775 if (Call->getCalledOperand()->stripPointerCasts() !=
776 SetJmp3.getCallee()->stripPointerCasts())
784 auto &BBColors = BlockColors[Call->getParent()];
786 bool InCleanup = isa<CleanupPadInst>(FuncletEntryBB->getFirstNonPHIIt());
788 IRBuilder<> Builder(Call);
791 Value *StateField = Builder.CreateStructGEP(RegNode->getAllocatedType(),
793 State = Builder.CreateLoad(Builder.getInt32Ty(), StateField);
795 State = Builder.getInt32(getStateForCall(BlockColors, FuncInfo, *Call));
797 rewriteSetJmpCall(Builder, F, *Call, State);
802 IRBuilder<> Builder(IP);
803 Value *StateField = Builder.CreateStructGEP(RegNode->getAllocatedType(),
805 Builder.CreateStore(Builder.getInt32(State), StateField);
812 if (Alloca->isStaticAlloca())
814 IRBuilder<> Builder(Alloca->getNextNonDebugInstruction());
816 Value *SP = Builder.CreateStackSave();
817 Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
821 if (II->getIntrinsicID() != Intrinsic::stackrestore)
823 IRBuilder<> Builder(II->getNextNonDebugInstruction());
825 Value *SP = Builder.CreateStackSave();
826 Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));