Win64EH.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-- llvm/Support/Win64EH.h ---Win64 EH Constants-------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file contains constants and structures used for implementing
  15. // exception handling on Win64 platforms. For more information, see
  16. // http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_SUPPORT_WIN64EH_H
  20. #define LLVM_SUPPORT_WIN64EH_H
  21. #include "llvm/Support/DataTypes.h"
  22. #include "llvm/Support/Endian.h"
  23. namespace llvm {
  24. namespace Win64EH {
  25. /// UnwindOpcodes - Enumeration whose values specify a single operation in
  26. /// the prolog of a function.
  27. enum UnwindOpcodes {
  28. // The following set of unwind opcodes is for x86_64. They are documented at
  29. // https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64.
  30. // Some generic values from this set are used for other architectures too.
  31. UOP_PushNonVol = 0,
  32. UOP_AllocLarge,
  33. UOP_AllocSmall,
  34. UOP_SetFPReg,
  35. UOP_SaveNonVol,
  36. UOP_SaveNonVolBig,
  37. UOP_Epilog,
  38. UOP_SpareCode,
  39. UOP_SaveXMM128,
  40. UOP_SaveXMM128Big,
  41. UOP_PushMachFrame,
  42. // The following set of unwind opcodes is for ARM64. They are documented at
  43. // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
  44. UOP_AllocMedium,
  45. UOP_SaveR19R20X,
  46. UOP_SaveFPLRX,
  47. UOP_SaveFPLR,
  48. UOP_SaveReg,
  49. UOP_SaveRegX,
  50. UOP_SaveRegP,
  51. UOP_SaveRegPX,
  52. UOP_SaveLRPair,
  53. UOP_SaveFReg,
  54. UOP_SaveFRegX,
  55. UOP_SaveFRegP,
  56. UOP_SaveFRegPX,
  57. UOP_SetFP,
  58. UOP_AddFP,
  59. UOP_Nop,
  60. UOP_End,
  61. UOP_SaveNext,
  62. UOP_TrapFrame,
  63. UOP_Context,
  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. // The following set of unwind opcodes is for ARM. They are documented at
  79. // https://docs.microsoft.com/en-us/cpp/build/arm-exception-handling
  80. // Stack allocations use UOP_AllocSmall, UOP_AllocLarge from above, plus
  81. // the following. AllocSmall, AllocLarge and AllocHuge represent a 16 bit
  82. // instruction, while the WideAlloc* opcodes represent a 32 bit instruction.
  83. // Small can represent a stack offset of 0x7f*4 (252) bytes, Medium can
  84. // represent up to 0x3ff*4 (4092) bytes, Large up to 0xffff*4 (262140) bytes,
  85. // and Huge up to 0xffffff*4 (67108860) bytes.
  86. UOP_AllocHuge,
  87. UOP_WideAllocMedium,
  88. UOP_WideAllocLarge,
  89. UOP_WideAllocHuge,
  90. UOP_WideSaveRegMask,
  91. UOP_SaveSP,
  92. UOP_SaveRegsR4R7LR,
  93. UOP_WideSaveRegsR4R11LR,
  94. UOP_SaveFRegD8D15,
  95. UOP_SaveRegMask,
  96. UOP_SaveLR,
  97. UOP_SaveFRegD0D15,
  98. UOP_SaveFRegD16D31,
  99. // Using UOP_Nop from above
  100. UOP_WideNop,
  101. // Using UOP_End from above
  102. UOP_EndNop,
  103. UOP_WideEndNop,
  104. // A custom unspecified opcode, consisting of one or more bytes. This
  105. // allows producing opcodes in the implementation defined/reserved range.
  106. UOP_Custom,
  107. };
  108. /// UnwindCode - This union describes a single operation in a function prolog,
  109. /// or part thereof.
  110. union UnwindCode {
  111. struct {
  112. uint8_t CodeOffset;
  113. uint8_t UnwindOpAndOpInfo;
  114. } u;
  115. support::ulittle16_t FrameOffset;
  116. uint8_t getUnwindOp() const {
  117. return u.UnwindOpAndOpInfo & 0x0F;
  118. }
  119. uint8_t getOpInfo() const {
  120. return (u.UnwindOpAndOpInfo >> 4) & 0x0F;
  121. }
  122. };
  123. enum {
  124. /// UNW_ExceptionHandler - Specifies that this function has an exception
  125. /// handler.
  126. UNW_ExceptionHandler = 0x01,
  127. /// UNW_TerminateHandler - Specifies that this function has a termination
  128. /// handler.
  129. UNW_TerminateHandler = 0x02,
  130. /// UNW_ChainInfo - Specifies that this UnwindInfo structure is chained to
  131. /// another one.
  132. UNW_ChainInfo = 0x04
  133. };
  134. /// RuntimeFunction - An entry in the table of functions with unwind info.
  135. struct RuntimeFunction {
  136. support::ulittle32_t StartAddress;
  137. support::ulittle32_t EndAddress;
  138. support::ulittle32_t UnwindInfoOffset;
  139. };
  140. /// UnwindInfo - An entry in the exception table.
  141. struct UnwindInfo {
  142. uint8_t VersionAndFlags;
  143. uint8_t PrologSize;
  144. uint8_t NumCodes;
  145. uint8_t FrameRegisterAndOffset;
  146. UnwindCode UnwindCodes[1];
  147. uint8_t getVersion() const {
  148. return VersionAndFlags & 0x07;
  149. }
  150. uint8_t getFlags() const {
  151. return (VersionAndFlags >> 3) & 0x1f;
  152. }
  153. uint8_t getFrameRegister() const {
  154. return FrameRegisterAndOffset & 0x0f;
  155. }
  156. uint8_t getFrameOffset() const {
  157. return (FrameRegisterAndOffset >> 4) & 0x0f;
  158. }
  159. // The data after unwindCodes depends on flags.
  160. // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows
  161. // the address of the language-specific exception handler.
  162. // If UNW_ChainInfo is set then follows a RuntimeFunction which defines
  163. // the chained unwind info.
  164. // For more information please see MSDN at:
  165. // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
  166. /// Return pointer to language specific data part of UnwindInfo.
  167. void *getLanguageSpecificData() {
  168. return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]);
  169. }
  170. /// Return pointer to language specific data part of UnwindInfo.
  171. const void *getLanguageSpecificData() const {
  172. return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes + 1) & ~1]);
  173. }
  174. /// Return image-relative offset of language-specific exception handler.
  175. uint32_t getLanguageSpecificHandlerOffset() const {
  176. return *reinterpret_cast<const support::ulittle32_t *>(
  177. getLanguageSpecificData());
  178. }
  179. /// Set image-relative offset of language-specific exception handler.
  180. void setLanguageSpecificHandlerOffset(uint32_t offset) {
  181. *reinterpret_cast<support::ulittle32_t *>(getLanguageSpecificData()) =
  182. offset;
  183. }
  184. /// Return pointer to exception-specific data.
  185. void *getExceptionData() {
  186. return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>(
  187. getLanguageSpecificData())+1);
  188. }
  189. /// Return pointer to chained unwind info.
  190. RuntimeFunction *getChainedFunctionEntry() {
  191. return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
  192. }
  193. /// Return pointer to chained unwind info.
  194. const RuntimeFunction *getChainedFunctionEntry() const {
  195. return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificData());
  196. }
  197. };
  198. } // End of namespace Win64EH
  199. } // End of namespace llvm
  200. #endif
  201. #ifdef __GNUC__
  202. #pragma GCC diagnostic pop
  203. #endif