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
21namespace llvm {
22namespace Win64EH {
23
24/// UnwindOpcodes - Enumeration whose values specify a single operation in
25/// the prolog of a function.
26enum UnwindOpcodes {
27 // The following set of unwind opcodes is for x86_64. They are documented at
28 // https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64.
29 // Some generic values from this set are used for other architectures too.
30 UOP_PushNonVol = 0,
31 UOP_AllocLarge,
32 UOP_AllocSmall,
33 UOP_SetFPReg,
34 UOP_SaveNonVol,
35 UOP_SaveNonVolBig,
36 UOP_Epilog,
37 UOP_SpareCode,
38 UOP_SaveXMM128,
39 UOP_SaveXMM128Big,
40 UOP_PushMachFrame,
41 // The following set of unwind opcodes is for ARM64. They are documented at
42 // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
43 UOP_AllocMedium,
44 UOP_SaveR19R20X,
45 UOP_SaveFPLRX,
46 UOP_SaveFPLR,
47 UOP_SaveReg,
48 UOP_SaveRegX,
49 UOP_SaveRegP,
50 UOP_SaveRegPX,
51 UOP_SaveLRPair,
52 UOP_SaveFReg,
53 UOP_SaveFRegX,
54 UOP_SaveFRegP,
55 UOP_SaveFRegPX,
56 UOP_SetFP,
57 UOP_AddFP,
58 UOP_Nop,
59 UOP_End,
60 UOP_SaveNext,
61 UOP_TrapFrame,
62 UOP_Context,
63 UOP_ECContext,
64 UOP_ClearUnwoundToCall,
65 UOP_PACSignLR,
66 UOP_SaveAnyRegI,
67 UOP_SaveAnyRegIP,
68 UOP_SaveAnyRegD,
69 UOP_SaveAnyRegDP,
70 UOP_SaveAnyRegQ,
71 UOP_SaveAnyRegQP,
72 UOP_SaveAnyRegIX,
73 UOP_SaveAnyRegIPX,
74 UOP_SaveAnyRegDX,
75 UOP_SaveAnyRegDPX,
76 UOP_SaveAnyRegQX,
77 UOP_SaveAnyRegQPX,
78
79 // The following set of unwind opcodes is for ARM. They are documented at
80 // https://docs.microsoft.com/en-us/cpp/build/arm-exception-handling
81
82 // Stack allocations use UOP_AllocSmall, UOP_AllocLarge from above, plus
83 // the following. AllocSmall, AllocLarge and AllocHuge represent a 16 bit
84 // instruction, while the WideAlloc* opcodes represent a 32 bit instruction.
85 // Small can represent a stack offset of 0x7f*4 (252) bytes, Medium can
86 // represent up to 0x3ff*4 (4092) bytes, Large up to 0xffff*4 (262140) bytes,
87 // and Huge up to 0xffffff*4 (67108860) bytes.
88 UOP_AllocHuge,
89 UOP_WideAllocMedium,
90 UOP_WideAllocLarge,
91 UOP_WideAllocHuge,
92
93 UOP_WideSaveRegMask,
94 UOP_SaveSP,
95 UOP_SaveRegsR4R7LR,
96 UOP_WideSaveRegsR4R11LR,
97 UOP_SaveFRegD8D15,
98 UOP_SaveRegMask,
99 UOP_SaveLR,
100 UOP_SaveFRegD0D15,
101 UOP_SaveFRegD16D31,
102 // Using UOP_Nop from above
103 UOP_WideNop,
104 // Using UOP_End from above
105 UOP_EndNop,
106 UOP_WideEndNop,
107 // A custom unspecified opcode, consisting of one or more bytes. This
108 // allows producing opcodes in the implementation defined/reserved range.
109 UOP_Custom,
110};
111
112/// UnwindCode - This union describes a single operation in a function prolog,
113/// or part thereof.
114union UnwindCode {
115 struct {
116 uint8_t CodeOffset;
117 uint8_t UnwindOpAndOpInfo;
118 } u;
119 support::ulittle16_t FrameOffset;
120
121 uint8_t getUnwindOp() const {
122 return u.UnwindOpAndOpInfo & 0x0F;
123 }
124 uint8_t getOpInfo() const {
125 return (u.UnwindOpAndOpInfo >> 4) & 0x0F;
126 }
127};
128
129enum {
130 /// UNW_ExceptionHandler - Specifies that this function has an exception
131 /// handler.
132 UNW_ExceptionHandler = 0x01,
133 /// UNW_TerminateHandler - Specifies that this function has a termination
134 /// handler.
135 UNW_TerminateHandler = 0x02,
136 /// UNW_ChainInfo - Specifies that this UnwindInfo structure is chained to
137 /// another one.
138 UNW_ChainInfo = 0x04
139};
140
141/// RuntimeFunction - An entry in the table of functions with unwind info.
142struct RuntimeFunction {
143 support::ulittle32_t StartAddress;
144 support::ulittle32_t EndAddress;
145 support::ulittle32_t UnwindInfoOffset;
146};
147
148/// UnwindInfo - An entry in the exception table.
149struct UnwindInfo {
150 uint8_t VersionAndFlags;
151 uint8_t PrologSize;
152 uint8_t NumCodes;
153 uint8_t FrameRegisterAndOffset;
154 UnwindCode UnwindCodes[1];
155
156 uint8_t getVersion() const {
157 return VersionAndFlags & 0x07;
158 }
159 uint8_t getFlags() const {
160 return (VersionAndFlags >> 3) & 0x1f;
161 }
162 uint8_t getFrameRegister() const {
163 return FrameRegisterAndOffset & 0x0f;
164 }
165 uint8_t getFrameOffset() const {
166 return (FrameRegisterAndOffset >> 4) & 0x0f;
167 }
168
169 // The data after unwindCodes depends on flags.
170 // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows
171 // the address of the language-specific exception handler.
172 // If UNW_ChainInfo is set then follows a RuntimeFunction which defines
173 // the chained unwind info.
174 // For more information please see MSDN at:
175 // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
176
177 /// Return pointer to language specific data part of UnwindInfo.
178 void *getLanguageSpecificData() {
179 return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]);
180 }
181
182 /// Return pointer to language specific data part of UnwindInfo.
183 const void *getLanguageSpecificData() const {
184 return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes + 1) & ~1]);
185 }
186
187 /// Return image-relative offset of language-specific exception handler.
188 uint32_t getLanguageSpecificHandlerOffset() const {
189 return *reinterpret_cast<const support::ulittle32_t *>(
190 getLanguageSpecificData());
191 }
192
193 /// Set image-relative offset of language-specific exception handler.
194 void setLanguageSpecificHandlerOffset(uint32_t offset) {
195 *reinterpret_cast<support::ulittle32_t *>(getLanguageSpecificData()) =
196 offset;
197 }
198
199 /// Return pointer to exception-specific data.
200 void *getExceptionData() {
201 return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>(
202 getLanguageSpecificData())+1);
203 }
204
205 /// Return pointer to chained unwind info.
206 RuntimeFunction *getChainedFunctionEntry() {
207 return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
208 }
209
210 /// Return pointer to chained unwind info.
211 const RuntimeFunction *getChainedFunctionEntry() const {
212 return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificData());
213 }
214};
215
216
217} // End of namespace Win64EH
218} // End of namespace llvm
219
220#endif
221

source code of llvm/include/llvm/Support/Win64EH.h