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