1 //===- EHPersonalities.cpp - Compute EH-related information ---------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/Analysis/EHPersonalities.h" 10 #include "llvm/ADT/StringSwitch.h" 11 #include "llvm/ADT/Triple.h" 12 #include "llvm/IR/CFG.h" 13 #include "llvm/IR/Constants.h" 14 #include "llvm/IR/Function.h" 15 #include "llvm/IR/Instructions.h" 16 #include "llvm/Support/Debug.h" 17 #include "llvm/Support/raw_ostream.h" 18 using namespace llvm; 19 20 /// See if the given exception handling personality function is one that we 21 /// understand. If so, return a description of it; otherwise return Unknown. 22 EHPersonality llvm::classifyEHPersonality(const Value *Pers) { 23 const GlobalValue *F = 24 Pers ? dyn_cast<GlobalValue>(Pers->stripPointerCasts()) : nullptr; 25 if (!F || !F->getValueType() || !F->getValueType()->isFunctionTy()) 26 return EHPersonality::Unknown; 27 return StringSwitch<EHPersonality>(F->getName()) 28 .Case("__gnat_eh_personality", EHPersonality::GNU_Ada) 29 .Case("__gxx_personality_v0", EHPersonality::GNU_CXX) 30 .Case("__gxx_personality_seh0", EHPersonality::GNU_CXX) 31 .Case("__gxx_personality_sj0", EHPersonality::GNU_CXX_SjLj) 32 .Case("__gcc_personality_v0", EHPersonality::GNU_C) 33 .Case("__gcc_personality_seh0", EHPersonality::GNU_C) 34 .Case("__gcc_personality_sj0", EHPersonality::GNU_C_SjLj) 35 .Case("__objc_personality_v0", EHPersonality::GNU_ObjC) 36 .Case("_except_handler3", EHPersonality::MSVC_X86SEH) 37 .Case("_except_handler4", EHPersonality::MSVC_X86SEH) 38 .Case("__C_specific_handler", EHPersonality::MSVC_TableSEH) 39 .Case("__CxxFrameHandler3", EHPersonality::MSVC_CXX) 40 .Case("ProcessCLRException", EHPersonality::CoreCLR) 41 .Case("rust_eh_personality", EHPersonality::Rust) 42 .Case("__gxx_wasm_personality_v0", EHPersonality::Wasm_CXX) 43 .Case("__xlcxx_personality_v1", EHPersonality::XL_CXX) 44 .Default(EHPersonality::Unknown); 45 } 46 47 StringRef llvm::getEHPersonalityName(EHPersonality Pers) { 48 switch (Pers) { 49 case EHPersonality::GNU_Ada: return "__gnat_eh_personality"; 50 case EHPersonality::GNU_CXX: return "__gxx_personality_v0"; 51 case EHPersonality::GNU_CXX_SjLj: return "__gxx_personality_sj0"; 52 case EHPersonality::GNU_C: return "__gcc_personality_v0"; 53 case EHPersonality::GNU_C_SjLj: return "__gcc_personality_sj0"; 54 case EHPersonality::GNU_ObjC: return "__objc_personality_v0"; 55 case EHPersonality::MSVC_X86SEH: return "_except_handler3"; 56 case EHPersonality::MSVC_TableSEH: 57 return "__C_specific_handler"; 58 case EHPersonality::MSVC_CXX: return "__CxxFrameHandler3"; 59 case EHPersonality::CoreCLR: return "ProcessCLRException"; 60 case EHPersonality::Rust: return "rust_eh_personality"; 61 case EHPersonality::Wasm_CXX: return "__gxx_wasm_personality_v0"; 62 case EHPersonality::XL_CXX: 63 return "__xlcxx_personality_v1"; 64 case EHPersonality::Unknown: llvm_unreachable("Unknown EHPersonality!"); 65 } 66 67 llvm_unreachable("Invalid EHPersonality!"); 68 } 69 70 EHPersonality llvm::getDefaultEHPersonality(const Triple &T) { 71 if (T.isPS5()) 72 return EHPersonality::GNU_CXX; 73 else 74 return EHPersonality::GNU_C; 75 } 76 77 bool llvm::canSimplifyInvokeNoUnwind(const Function *F) { 78 EHPersonality Personality = classifyEHPersonality(F->getPersonalityFn()); 79 // We can't simplify any invokes to nounwind functions if the personality 80 // function wants to catch asynch exceptions. The nounwind attribute only 81 // implies that the function does not throw synchronous exceptions. 82 return !isAsynchronousEHPersonality(Personality); 83 } 84 85 DenseMap<BasicBlock *, ColorVector> llvm::colorEHFunclets(Function &F) { 86 SmallVector<std::pair<BasicBlock *, BasicBlock *>, 16> Worklist; 87 BasicBlock *EntryBlock = &F.getEntryBlock(); 88 DenseMap<BasicBlock *, ColorVector> BlockColors; 89 90 // Build up the color map, which maps each block to its set of 'colors'. 91 // For any block B the "colors" of B are the set of funclets F (possibly 92 // including a root "funclet" representing the main function) such that 93 // F will need to directly contain B or a copy of B (where the term "directly 94 // contain" is used to distinguish from being "transitively contained" in 95 // a nested funclet). 96 // 97 // Note: Despite not being a funclet in the truest sense, a catchswitch is 98 // considered to belong to its own funclet for the purposes of coloring. 99 100 DEBUG_WITH_TYPE("winehprepare-coloring", dbgs() << "\nColoring funclets for " 101 << F.getName() << "\n"); 102 103 Worklist.push_back({EntryBlock, EntryBlock}); 104 105 while (!Worklist.empty()) { 106 BasicBlock *Visiting; 107 BasicBlock *Color; 108 std::tie(Visiting, Color) = Worklist.pop_back_val(); 109 DEBUG_WITH_TYPE("winehprepare-coloring", 110 dbgs() << "Visiting " << Visiting->getName() << ", " 111 << Color->getName() << "\n"); 112 Instruction *VisitingHead = Visiting->getFirstNonPHI(); 113 if (VisitingHead->isEHPad()) { 114 // Mark this funclet head as a member of itself. 115 Color = Visiting; 116 } 117 // Note that this is a member of the given color. 118 ColorVector &Colors = BlockColors[Visiting]; 119 if (!is_contained(Colors, Color)) 120 Colors.push_back(Color); 121 else 122 continue; 123 124 DEBUG_WITH_TYPE("winehprepare-coloring", 125 dbgs() << " Assigned color \'" << Color->getName() 126 << "\' to block \'" << Visiting->getName() 127 << "\'.\n"); 128 129 BasicBlock *SuccColor = Color; 130 Instruction *Terminator = Visiting->getTerminator(); 131 if (auto *CatchRet = dyn_cast<CatchReturnInst>(Terminator)) { 132 Value *ParentPad = CatchRet->getCatchSwitchParentPad(); 133 if (isa<ConstantTokenNone>(ParentPad)) 134 SuccColor = EntryBlock; 135 else 136 SuccColor = cast<Instruction>(ParentPad)->getParent(); 137 } 138 139 for (BasicBlock *Succ : successors(Visiting)) 140 Worklist.push_back({Succ, SuccColor}); 141 } 142 return BlockColors; 143 } 144