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_SaveFPLRX, 42 UOP_SaveFPLR, 43 UOP_SaveReg, 44 UOP_SaveRegX, 45 UOP_SaveRegP, 46 UOP_SaveRegPX, 47 UOP_SaveFReg, 48 UOP_SaveFRegX, 49 UOP_SaveFRegP, 50 UOP_SaveFRegPX, 51 UOP_SetFP, 52 UOP_AddFP, 53 UOP_Nop, 54 UOP_End 55 }; 56 57 /// UnwindCode - This union describes a single operation in a function prolog, 58 /// or part thereof. 59 union UnwindCode { 60 struct { 61 uint8_t CodeOffset; 62 uint8_t UnwindOpAndOpInfo; 63 } u; 64 support::ulittle16_t FrameOffset; 65 getUnwindOp()66 uint8_t getUnwindOp() const { 67 return u.UnwindOpAndOpInfo & 0x0F; 68 } getOpInfo()69 uint8_t getOpInfo() const { 70 return (u.UnwindOpAndOpInfo >> 4) & 0x0F; 71 } 72 }; 73 74 enum { 75 /// UNW_ExceptionHandler - Specifies that this function has an exception 76 /// handler. 77 UNW_ExceptionHandler = 0x01, 78 /// UNW_TerminateHandler - Specifies that this function has a termination 79 /// handler. 80 UNW_TerminateHandler = 0x02, 81 /// UNW_ChainInfo - Specifies that this UnwindInfo structure is chained to 82 /// another one. 83 UNW_ChainInfo = 0x04 84 }; 85 86 /// RuntimeFunction - An entry in the table of functions with unwind info. 87 struct RuntimeFunction { 88 support::ulittle32_t StartAddress; 89 support::ulittle32_t EndAddress; 90 support::ulittle32_t UnwindInfoOffset; 91 }; 92 93 /// UnwindInfo - An entry in the exception table. 94 struct UnwindInfo { 95 uint8_t VersionAndFlags; 96 uint8_t PrologSize; 97 uint8_t NumCodes; 98 uint8_t FrameRegisterAndOffset; 99 UnwindCode UnwindCodes[1]; 100 getVersionUnwindInfo101 uint8_t getVersion() const { 102 return VersionAndFlags & 0x07; 103 } getFlagsUnwindInfo104 uint8_t getFlags() const { 105 return (VersionAndFlags >> 3) & 0x1f; 106 } getFrameRegisterUnwindInfo107 uint8_t getFrameRegister() const { 108 return FrameRegisterAndOffset & 0x0f; 109 } getFrameOffsetUnwindInfo110 uint8_t getFrameOffset() const { 111 return (FrameRegisterAndOffset >> 4) & 0x0f; 112 } 113 114 // The data after unwindCodes depends on flags. 115 // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows 116 // the address of the language-specific exception handler. 117 // If UNW_ChainInfo is set then follows a RuntimeFunction which defines 118 // the chained unwind info. 119 // For more information please see MSDN at: 120 // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx 121 122 /// Return pointer to language specific data part of UnwindInfo. getLanguageSpecificDataUnwindInfo123 void *getLanguageSpecificData() { 124 return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]); 125 } 126 127 /// Return pointer to language specific data part of UnwindInfo. getLanguageSpecificDataUnwindInfo128 const void *getLanguageSpecificData() const { 129 return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes + 1) & ~1]); 130 } 131 132 /// Return image-relative offset of language-specific exception handler. getLanguageSpecificHandlerOffsetUnwindInfo133 uint32_t getLanguageSpecificHandlerOffset() const { 134 return *reinterpret_cast<const support::ulittle32_t *>( 135 getLanguageSpecificData()); 136 } 137 138 /// Set image-relative offset of language-specific exception handler. setLanguageSpecificHandlerOffsetUnwindInfo139 void setLanguageSpecificHandlerOffset(uint32_t offset) { 140 *reinterpret_cast<support::ulittle32_t *>(getLanguageSpecificData()) = 141 offset; 142 } 143 144 /// Return pointer to exception-specific data. getExceptionDataUnwindInfo145 void *getExceptionData() { 146 return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>( 147 getLanguageSpecificData())+1); 148 } 149 150 /// Return pointer to chained unwind info. getChainedFunctionEntryUnwindInfo151 RuntimeFunction *getChainedFunctionEntry() { 152 return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData()); 153 } 154 155 /// Return pointer to chained unwind info. getChainedFunctionEntryUnwindInfo156 const RuntimeFunction *getChainedFunctionEntry() const { 157 return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificData()); 158 } 159 }; 160 161 162 } // End of namespace Win64EH 163 } // End of namespace llvm 164 165 #endif 166