blob: 9359fcb4286a99b3ffab8e11dca4dd65a51b0992 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===-- llvm/Support/Win64EH.h ---Win64 EH Constants-------------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
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 UOP_PushNonVol = 0,
28 UOP_AllocLarge,
29 UOP_AllocSmall,
30 UOP_SetFPReg,
31 UOP_SaveNonVol,
32 UOP_SaveNonVolBig,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020033 UOP_Epilog,
34 UOP_SpareCode,
35 UOP_SaveXMM128,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010036 UOP_SaveXMM128Big,
Andrew Walbran16937d02019-10-22 13:54:20 +010037 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,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020041 UOP_SaveR19R20X,
Andrew Walbran16937d02019-10-22 13:54:20 +010042 UOP_SaveFPLRX,
43 UOP_SaveFPLR,
44 UOP_SaveReg,
45 UOP_SaveRegX,
46 UOP_SaveRegP,
47 UOP_SaveRegPX,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020048 UOP_SaveLRPair,
Andrew Walbran16937d02019-10-22 13:54:20 +010049 UOP_SaveFReg,
50 UOP_SaveFRegX,
51 UOP_SaveFRegP,
52 UOP_SaveFRegPX,
53 UOP_SetFP,
54 UOP_AddFP,
55 UOP_Nop,
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020056 UOP_End,
57 UOP_SaveNext,
58 UOP_TrapFrame,
59 UOP_Context,
60 UOP_ClearUnwoundToCall
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010061};
62
63/// UnwindCode - This union describes a single operation in a function prolog,
64/// or part thereof.
65union 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
80enum {
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.
93struct 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.
100struct 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
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100128 /// Return pointer to language specific data part of UnwindInfo.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100129 void *getLanguageSpecificData() {
130 return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]);
131 }
132
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100133 /// Return pointer to language specific data part of UnwindInfo.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100134 const void *getLanguageSpecificData() const {
135 return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes + 1) & ~1]);
136 }
137
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100138 /// Return image-relative offset of language-specific exception handler.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100139 uint32_t getLanguageSpecificHandlerOffset() const {
140 return *reinterpret_cast<const support::ulittle32_t *>(
141 getLanguageSpecificData());
142 }
143
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100144 /// Set image-relative offset of language-specific exception handler.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100145 void setLanguageSpecificHandlerOffset(uint32_t offset) {
146 *reinterpret_cast<support::ulittle32_t *>(getLanguageSpecificData()) =
147 offset;
148 }
149
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100150 /// Return pointer to exception-specific data.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100151 void *getExceptionData() {
152 return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>(
153 getLanguageSpecificData())+1);
154 }
155
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100156 /// Return pointer to chained unwind info.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100157 RuntimeFunction *getChainedFunctionEntry() {
158 return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
159 }
160
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100161 /// Return pointer to chained unwind info.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100162 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