Home | History | Annotate | Line # | Download | only in MC
      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 
     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;
     60   FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel)
     61       : Begin(BeginFuncEHLabel), Function(Function) {}
     62   FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel,
     63             const FrameInfo *ChainedParent)
     64       : Begin(BeginFuncEHLabel), Function(Function),
     65         ChainedParent(ChainedParent) {}
     66 
     67   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