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 InstructionInstruction27 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 54 int LastFrameInst = -1; 55 const FrameInfo *ChainedParent = nullptr; 56 std::vector<Instruction> Instructions; 57 MapVector<MCSymbol*, std::vector<Instruction>> EpilogMap; 58 59 FrameInfo() = default; FrameInfoFrameInfo60 FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel) 61 : Begin(BeginFuncEHLabel), Function(Function) {} FrameInfoFrameInfo62 FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel, 63 const FrameInfo *ChainedParent) 64 : Begin(BeginFuncEHLabel), Function(Function), 65 ChainedParent(ChainedParent) {} 66 emptyFrameInfo67 bool empty() const { 68 if (!Instructions.empty()) 69 return false; 70 for (const auto &E : EpilogMap) 71 if (!E.second.empty()) 72 return false; 73 return true; 74 } 75 }; 76 77 class UnwindEmitter { 78 public: 79 virtual ~UnwindEmitter(); 80 81 /// This emits the unwind info sections (.pdata and .xdata in PE/COFF). 82 virtual void Emit(MCStreamer &Streamer) const = 0; 83 virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI, 84 bool HandlerData) const = 0; 85 }; 86 } 87 } 88 89 #endif 90