1 //===- MCWinEH.h - Windows Unwinding Support --------------------*- C++ -*-===// 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 #ifndef LLVM_MC_MCWINEH_H 10 #define LLVM_MC_MCWINEH_H 11 12 #include "llvm/ADT/MapVector.h" 13 #include <vector> 14 15 namespace llvm { 16 class MCSection; 17 class MCStreamer; 18 class MCSymbol; 19 20 namespace WinEH { 21 struct Instruction { 22 const MCSymbol *Label; 23 unsigned Offset; 24 unsigned Register; 25 unsigned Operation; 26 27 Instruction(unsigned Op, MCSymbol *L, unsigned Reg, unsigned Off) 28 : Label(L), Offset(Off), Register(Reg), Operation(Op) {} 29 30 bool operator==(const Instruction &I) const { 31 // Check whether two instructions refer to the same operation 32 // applied at a different spot (i.e. pointing at a different label). 33 return Offset == I.Offset && Register == I.Register && 34 Operation == I.Operation; 35 } 36 bool operator!=(const Instruction &I) const { return !(*this == I); } 37 }; 38 39 struct FrameInfo { 40 const MCSymbol *Begin = nullptr; 41 const MCSymbol *End = nullptr; 42 const MCSymbol *FuncletOrFuncEnd = nullptr; 43 const MCSymbol *ExceptionHandler = nullptr; 44 const MCSymbol *Function = nullptr; 45 const MCSymbol *PrologEnd = nullptr; 46 const MCSymbol *Symbol = nullptr; 47 MCSection *TextSection = nullptr; 48 uint32_t PackedInfo = 0; 49 50 bool HandlesUnwind = false; 51 bool HandlesExceptions = false; 52 bool EmitAttempted = false; 53 bool Fragment = false; 54 55 int LastFrameInst = -1; 56 const FrameInfo *ChainedParent = nullptr; 57 std::vector<Instruction> Instructions; 58 struct Epilog { 59 std::vector<Instruction> Instructions; 60 unsigned Condition; 61 MCSymbol *End; 62 }; 63 MapVector<MCSymbol *, Epilog> EpilogMap; 64 65 FrameInfo() = default; 66 FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel) 67 : Begin(BeginFuncEHLabel), Function(Function) {} 68 FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel, 69 const FrameInfo *ChainedParent) 70 : Begin(BeginFuncEHLabel), Function(Function), 71 ChainedParent(ChainedParent) {} 72 73 bool empty() const { 74 if (!Instructions.empty()) 75 return false; 76 for (const auto &E : EpilogMap) 77 if (!E.second.Instructions.empty()) 78 return false; 79 return true; 80 } 81 }; 82 83 class UnwindEmitter { 84 public: 85 virtual ~UnwindEmitter(); 86 87 /// This emits the unwind info sections (.pdata and .xdata in PE/COFF). 88 virtual void Emit(MCStreamer &Streamer) const = 0; 89 virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI, 90 bool HandlerData) const = 0; 91 }; 92 } 93 } 94 95 #endif 96