Home | History | Annotate | Line # | Download | only in Support
      1 //===-- llvm/Support/Win64EH.h ---Win64 EH Constants-------------*- 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 // This file contains constants and structures used for implementing
     10 // exception handling on Win64 platforms. For more information, see
     11 // http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_SUPPORT_WIN64EH_H
     16 #define LLVM_SUPPORT_WIN64EH_H
     17 
     18 #include "llvm/Support/DataTypes.h"
     19 #include "llvm/Support/Endian.h"
     20 
     21 namespace llvm {
     22 namespace Win64EH {
     23 
     24 /// UnwindOpcodes - Enumeration whose values specify a single operation in
     25 /// the prolog of a function.
     26 enum UnwindOpcodes {
     27   UOP_PushNonVol = 0,
     28   UOP_AllocLarge,
     29   UOP_AllocSmall,
     30   UOP_SetFPReg,
     31   UOP_SaveNonVol,
     32   UOP_SaveNonVolBig,
     33   UOP_Epilog,
     34   UOP_SpareCode,
     35   UOP_SaveXMM128,
     36   UOP_SaveXMM128Big,
     37   UOP_PushMachFrame,
     38   // The following set of unwind opcodes is for ARM64.  They are documented at
     39   // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
     40   UOP_AllocMedium,
     41   UOP_SaveR19R20X,
     42   UOP_SaveFPLRX,
     43   UOP_SaveFPLR,
     44   UOP_SaveReg,
     45   UOP_SaveRegX,
     46   UOP_SaveRegP,
     47   UOP_SaveRegPX,
     48   UOP_SaveLRPair,
     49   UOP_SaveFReg,
     50   UOP_SaveFRegX,
     51   UOP_SaveFRegP,
     52   UOP_SaveFRegPX,
     53   UOP_SetFP,
     54   UOP_AddFP,
     55   UOP_Nop,
     56   UOP_End,
     57   UOP_SaveNext,
     58   UOP_TrapFrame,
     59   UOP_Context,
     60   UOP_ClearUnwoundToCall
     61 };
     62 
     63 /// UnwindCode - This union describes a single operation in a function prolog,
     64 /// or part thereof.
     65 union UnwindCode {
     66   struct {
     67     uint8_t CodeOffset;
     68     uint8_t UnwindOpAndOpInfo;
     69   } u;
     70   support::ulittle16_t FrameOffset;
     71 
     72   uint8_t getUnwindOp() const {
     73     return u.UnwindOpAndOpInfo & 0x0F;
     74   }
     75   uint8_t getOpInfo() const {
     76     return (u.UnwindOpAndOpInfo >> 4) & 0x0F;
     77   }
     78 };
     79 
     80 enum {
     81   /// UNW_ExceptionHandler - Specifies that this function has an exception
     82   /// handler.
     83   UNW_ExceptionHandler = 0x01,
     84   /// UNW_TerminateHandler - Specifies that this function has a termination
     85   /// handler.
     86   UNW_TerminateHandler = 0x02,
     87   /// UNW_ChainInfo - Specifies that this UnwindInfo structure is chained to
     88   /// another one.
     89   UNW_ChainInfo = 0x04
     90 };
     91 
     92 /// RuntimeFunction - An entry in the table of functions with unwind info.
     93 struct RuntimeFunction {
     94   support::ulittle32_t StartAddress;
     95   support::ulittle32_t EndAddress;
     96   support::ulittle32_t UnwindInfoOffset;
     97 };
     98 
     99 /// UnwindInfo - An entry in the exception table.
    100 struct UnwindInfo {
    101   uint8_t VersionAndFlags;
    102   uint8_t PrologSize;
    103   uint8_t NumCodes;
    104   uint8_t FrameRegisterAndOffset;
    105   UnwindCode UnwindCodes[1];
    106 
    107   uint8_t getVersion() const {
    108     return VersionAndFlags & 0x07;
    109   }
    110   uint8_t getFlags() const {
    111     return (VersionAndFlags >> 3) & 0x1f;
    112   }
    113   uint8_t getFrameRegister() const {
    114     return FrameRegisterAndOffset & 0x0f;
    115   }
    116   uint8_t getFrameOffset() const {
    117     return (FrameRegisterAndOffset >> 4) & 0x0f;
    118   }
    119 
    120   // The data after unwindCodes depends on flags.
    121   // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows
    122   // the address of the language-specific exception handler.
    123   // If UNW_ChainInfo is set then follows a RuntimeFunction which defines
    124   // the chained unwind info.
    125   // For more information please see MSDN at:
    126   // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
    127 
    128   /// Return pointer to language specific data part of UnwindInfo.
    129   void *getLanguageSpecificData() {
    130     return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]);
    131   }
    132 
    133   /// Return pointer to language specific data part of UnwindInfo.
    134   const void *getLanguageSpecificData() const {
    135     return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes + 1) & ~1]);
    136   }
    137 
    138   /// Return image-relative offset of language-specific exception handler.
    139   uint32_t getLanguageSpecificHandlerOffset() const {
    140     return *reinterpret_cast<const support::ulittle32_t *>(
    141                getLanguageSpecificData());
    142   }
    143 
    144   /// Set image-relative offset of language-specific exception handler.
    145   void setLanguageSpecificHandlerOffset(uint32_t offset) {
    146     *reinterpret_cast<support::ulittle32_t *>(getLanguageSpecificData()) =
    147         offset;
    148   }
    149 
    150   /// Return pointer to exception-specific data.
    151   void *getExceptionData() {
    152     return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>(
    153                                                   getLanguageSpecificData())+1);
    154   }
    155 
    156   /// Return pointer to chained unwind info.
    157   RuntimeFunction *getChainedFunctionEntry() {
    158     return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
    159   }
    160 
    161   /// Return pointer to chained unwind info.
    162   const RuntimeFunction *getChainedFunctionEntry() const {
    163     return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificData());
    164   }
    165 };
    166 
    167 
    168 } // End of namespace Win64EH
    169 } // End of namespace llvm
    170 
    171 #endif
    172