blob: bdd23b41594ee0154061a238c4392c888f21b678 [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,
33 UOP_SaveXMM128 = 8,
34 UOP_SaveXMM128Big,
Andrew Walbran16937d02019-10-22 13:54:20 +010035 UOP_PushMachFrame,
36 // The following set of unwind opcodes is for ARM64. They are documented at
37 // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
38 UOP_AllocMedium,
39 UOP_SaveFPLRX,
40 UOP_SaveFPLR,
41 UOP_SaveReg,
42 UOP_SaveRegX,
43 UOP_SaveRegP,
44 UOP_SaveRegPX,
45 UOP_SaveFReg,
46 UOP_SaveFRegX,
47 UOP_SaveFRegP,
48 UOP_SaveFRegPX,
49 UOP_SetFP,
50 UOP_AddFP,
51 UOP_Nop,
52 UOP_End
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010053};
54
55/// UnwindCode - This union describes a single operation in a function prolog,
56/// or part thereof.
57union UnwindCode {
58 struct {
59 uint8_t CodeOffset;
60 uint8_t UnwindOpAndOpInfo;
61 } u;
62 support::ulittle16_t FrameOffset;
63
64 uint8_t getUnwindOp() const {
65 return u.UnwindOpAndOpInfo & 0x0F;
66 }
67 uint8_t getOpInfo() const {
68 return (u.UnwindOpAndOpInfo >> 4) & 0x0F;
69 }
70};
71
72enum {
73 /// UNW_ExceptionHandler - Specifies that this function has an exception
74 /// handler.
75 UNW_ExceptionHandler = 0x01,
76 /// UNW_TerminateHandler - Specifies that this function has a termination
77 /// handler.
78 UNW_TerminateHandler = 0x02,
79 /// UNW_ChainInfo - Specifies that this UnwindInfo structure is chained to
80 /// another one.
81 UNW_ChainInfo = 0x04
82};
83
84/// RuntimeFunction - An entry in the table of functions with unwind info.
85struct RuntimeFunction {
86 support::ulittle32_t StartAddress;
87 support::ulittle32_t EndAddress;
88 support::ulittle32_t UnwindInfoOffset;
89};
90
91/// UnwindInfo - An entry in the exception table.
92struct UnwindInfo {
93 uint8_t VersionAndFlags;
94 uint8_t PrologSize;
95 uint8_t NumCodes;
96 uint8_t FrameRegisterAndOffset;
97 UnwindCode UnwindCodes[1];
98
99 uint8_t getVersion() const {
100 return VersionAndFlags & 0x07;
101 }
102 uint8_t getFlags() const {
103 return (VersionAndFlags >> 3) & 0x1f;
104 }
105 uint8_t getFrameRegister() const {
106 return FrameRegisterAndOffset & 0x0f;
107 }
108 uint8_t getFrameOffset() const {
109 return (FrameRegisterAndOffset >> 4) & 0x0f;
110 }
111
112 // The data after unwindCodes depends on flags.
113 // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows
114 // the address of the language-specific exception handler.
115 // If UNW_ChainInfo is set then follows a RuntimeFunction which defines
116 // the chained unwind info.
117 // For more information please see MSDN at:
118 // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
119
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100120 /// Return pointer to language specific data part of UnwindInfo.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100121 void *getLanguageSpecificData() {
122 return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]);
123 }
124
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100125 /// Return pointer to language specific data part of UnwindInfo.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100126 const void *getLanguageSpecificData() const {
127 return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes + 1) & ~1]);
128 }
129
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100130 /// Return image-relative offset of language-specific exception handler.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100131 uint32_t getLanguageSpecificHandlerOffset() const {
132 return *reinterpret_cast<const support::ulittle32_t *>(
133 getLanguageSpecificData());
134 }
135
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100136 /// Set image-relative offset of language-specific exception handler.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100137 void setLanguageSpecificHandlerOffset(uint32_t offset) {
138 *reinterpret_cast<support::ulittle32_t *>(getLanguageSpecificData()) =
139 offset;
140 }
141
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100142 /// Return pointer to exception-specific data.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100143 void *getExceptionData() {
144 return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>(
145 getLanguageSpecificData())+1);
146 }
147
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100148 /// Return pointer to chained unwind info.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100149 RuntimeFunction *getChainedFunctionEntry() {
150 return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
151 }
152
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100153 /// Return pointer to chained unwind info.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100154 const RuntimeFunction *getChainedFunctionEntry() const {
155 return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificData());
156 }
157};
158
159
160} // End of namespace Win64EH
161} // End of namespace llvm
162
163#endif