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