1*700637cbSDimitry Andric //===-- EHContGuardTargets.cpp - EH continuation target symbols -*- C++ -*-===// 2*700637cbSDimitry Andric // 3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*700637cbSDimitry Andric // 7*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 8*700637cbSDimitry Andric /// 9*700637cbSDimitry Andric /// \file 10*700637cbSDimitry Andric /// This file contains a machine function pass to insert a symbol before each 11*700637cbSDimitry Andric /// valid target where the unwinder in Windows may continue exectution after an 12*700637cbSDimitry Andric /// exception is thrown and store this in the MachineFunction's EHContTargets 13*700637cbSDimitry Andric /// vector. This will be used to emit the table of valid targets used by Windows 14*700637cbSDimitry Andric /// EH Continuation Guard. 15*700637cbSDimitry Andric /// 16*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 17*700637cbSDimitry Andric 18*700637cbSDimitry Andric #include "llvm/ADT/Statistic.h" 19*700637cbSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 20*700637cbSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 21*700637cbSDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 22*700637cbSDimitry Andric #include "llvm/CodeGen/Passes.h" 23*700637cbSDimitry Andric #include "llvm/IR/Module.h" 24*700637cbSDimitry Andric #include "llvm/InitializePasses.h" 25*700637cbSDimitry Andric 26*700637cbSDimitry Andric using namespace llvm; 27*700637cbSDimitry Andric 28*700637cbSDimitry Andric #define DEBUG_TYPE "ehcontguard-catchret" 29*700637cbSDimitry Andric 30*700637cbSDimitry Andric STATISTIC(EHContGuardTargetsFound, "Number of EHCont Guard targets"); 31*700637cbSDimitry Andric 32*700637cbSDimitry Andric namespace { 33*700637cbSDimitry Andric 34*700637cbSDimitry Andric /// MachineFunction pass to insert a symbol before each valid catchret target 35*700637cbSDimitry Andric /// and store these in the MachineFunction's CatchRetTargets vector. 36*700637cbSDimitry Andric class EHContGuardTargets : public MachineFunctionPass { 37*700637cbSDimitry Andric public: 38*700637cbSDimitry Andric static char ID; 39*700637cbSDimitry Andric EHContGuardTargets()40*700637cbSDimitry Andric EHContGuardTargets() : MachineFunctionPass(ID) { 41*700637cbSDimitry Andric initializeEHContGuardTargetsPass(*PassRegistry::getPassRegistry()); 42*700637cbSDimitry Andric } 43*700637cbSDimitry Andric getPassName() const44*700637cbSDimitry Andric StringRef getPassName() const override { 45*700637cbSDimitry Andric return "EH Cont Guard catchret targets"; 46*700637cbSDimitry Andric } 47*700637cbSDimitry Andric 48*700637cbSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 49*700637cbSDimitry Andric }; 50*700637cbSDimitry Andric 51*700637cbSDimitry Andric } // end anonymous namespace 52*700637cbSDimitry Andric 53*700637cbSDimitry Andric char EHContGuardTargets::ID = 0; 54*700637cbSDimitry Andric 55*700637cbSDimitry Andric INITIALIZE_PASS(EHContGuardTargets, "EHContGuardTargets", 56*700637cbSDimitry Andric "Insert symbols at valid targets for /guard:ehcont", false, 57*700637cbSDimitry Andric false) createEHContGuardTargetsPass()58*700637cbSDimitry AndricFunctionPass *llvm::createEHContGuardTargetsPass() { 59*700637cbSDimitry Andric return new EHContGuardTargets(); 60*700637cbSDimitry Andric } 61*700637cbSDimitry Andric runOnMachineFunction(MachineFunction & MF)62*700637cbSDimitry Andricbool EHContGuardTargets::runOnMachineFunction(MachineFunction &MF) { 63*700637cbSDimitry Andric 64*700637cbSDimitry Andric // Skip modules for which the ehcontguard flag is not set. 65*700637cbSDimitry Andric if (!MF.getFunction().getParent()->getModuleFlag("ehcontguard")) 66*700637cbSDimitry Andric return false; 67*700637cbSDimitry Andric 68*700637cbSDimitry Andric // Skip functions that do not have targets 69*700637cbSDimitry Andric if (!MF.hasEHContTarget()) 70*700637cbSDimitry Andric return false; 71*700637cbSDimitry Andric 72*700637cbSDimitry Andric bool Result = false; 73*700637cbSDimitry Andric 74*700637cbSDimitry Andric for (MachineBasicBlock &MBB : MF) { 75*700637cbSDimitry Andric if (MBB.isEHContTarget()) { 76*700637cbSDimitry Andric MF.addEHContTarget(MBB.getEHContSymbol()); 77*700637cbSDimitry Andric EHContGuardTargetsFound++; 78*700637cbSDimitry Andric Result = true; 79*700637cbSDimitry Andric } 80*700637cbSDimitry Andric } 81*700637cbSDimitry Andric 82*700637cbSDimitry Andric return Result; 83*700637cbSDimitry Andric } 84