Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:16

0001 //===- MCWinEH.h - Windows Unwinding Support --------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_MC_MCWINEH_H
0010 #define LLVM_MC_MCWINEH_H
0011 
0012 #include "llvm/ADT/MapVector.h"
0013 #include <vector>
0014 
0015 namespace llvm {
0016 class MCSection;
0017 class MCStreamer;
0018 class MCSymbol;
0019 
0020 namespace WinEH {
0021 struct Instruction {
0022   const MCSymbol *Label;
0023   unsigned Offset;
0024   unsigned Register;
0025   unsigned Operation;
0026 
0027   Instruction(unsigned Op, MCSymbol *L, unsigned Reg, unsigned Off)
0028     : Label(L), Offset(Off), Register(Reg), Operation(Op) {}
0029 
0030   bool operator==(const Instruction &I) const {
0031     // Check whether two instructions refer to the same operation
0032     // applied at a different spot (i.e. pointing at a different label).
0033     return Offset == I.Offset && Register == I.Register &&
0034            Operation == I.Operation;
0035   }
0036   bool operator!=(const Instruction &I) const { return !(*this == I); }
0037 };
0038 
0039 struct FrameInfo {
0040   const MCSymbol *Begin = nullptr;
0041   const MCSymbol *End = nullptr;
0042   const MCSymbol *FuncletOrFuncEnd = nullptr;
0043   const MCSymbol *ExceptionHandler = nullptr;
0044   const MCSymbol *Function = nullptr;
0045   const MCSymbol *PrologEnd = nullptr;
0046   const MCSymbol *Symbol = nullptr;
0047   MCSection *TextSection = nullptr;
0048   uint32_t PackedInfo = 0;
0049   uint32_t PrologCodeBytes = 0;
0050 
0051   bool HandlesUnwind = false;
0052   bool HandlesExceptions = false;
0053   bool EmitAttempted = false;
0054   bool Fragment = false;
0055 
0056   int LastFrameInst = -1;
0057   const FrameInfo *ChainedParent = nullptr;
0058   std::vector<Instruction> Instructions;
0059   struct Epilog {
0060     std::vector<Instruction> Instructions;
0061     unsigned Condition;
0062     MCSymbol *End;
0063   };
0064   MapVector<MCSymbol *, Epilog> EpilogMap;
0065 
0066   // For splitting unwind info of large functions
0067   struct Segment {
0068     int64_t Offset;
0069     int64_t Length;
0070     bool HasProlog;
0071     MCSymbol *Symbol = nullptr;
0072     // Map an Epilog's symbol to its offset within the function.
0073     MapVector<MCSymbol *, int64_t> Epilogs;
0074 
0075     Segment(int64_t Offset, int64_t Length, bool HasProlog = false)
0076         : Offset(Offset), Length(Length), HasProlog(HasProlog) {}
0077   };
0078 
0079   std::vector<Segment> Segments;
0080 
0081   FrameInfo() = default;
0082   FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel)
0083       : Begin(BeginFuncEHLabel), Function(Function) {}
0084   FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel,
0085             const FrameInfo *ChainedParent)
0086       : Begin(BeginFuncEHLabel), Function(Function),
0087         ChainedParent(ChainedParent) {}
0088 
0089   bool empty() const {
0090     if (!Instructions.empty())
0091       return false;
0092     for (const auto &E : EpilogMap)
0093       if (!E.second.Instructions.empty())
0094         return false;
0095     return true;
0096   }
0097 };
0098 
0099 class UnwindEmitter {
0100 public:
0101   virtual ~UnwindEmitter();
0102 
0103   /// This emits the unwind info sections (.pdata and .xdata in PE/COFF).
0104   virtual void Emit(MCStreamer &Streamer) const = 0;
0105   virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI,
0106                               bool HandlerData) const = 0;
0107 };
0108 }
0109 }
0110 
0111 #endif