Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:35

0001 //===-- llvm/Support/Win64EH.h ---Win64 EH Constants-------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file contains constants and structures used for implementing
0010 // exception handling on Win64 platforms. For more information, see
0011 // http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx
0012 //
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_SUPPORT_WIN64EH_H
0016 #define LLVM_SUPPORT_WIN64EH_H
0017 
0018 #include "llvm/Support/DataTypes.h"
0019 #include "llvm/Support/Endian.h"
0020 
0021 namespace llvm {
0022 namespace Win64EH {
0023 
0024 /// UnwindOpcodes - Enumeration whose values specify a single operation in
0025 /// the prolog of a function.
0026 enum UnwindOpcodes {
0027   // The following set of unwind opcodes is for x86_64.  They are documented at
0028   // https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64.
0029   // Some generic values from this set are used for other architectures too.
0030   UOP_PushNonVol = 0,
0031   UOP_AllocLarge,
0032   UOP_AllocSmall,
0033   UOP_SetFPReg,
0034   UOP_SaveNonVol,
0035   UOP_SaveNonVolBig,
0036   UOP_Epilog,
0037   UOP_SpareCode,
0038   UOP_SaveXMM128,
0039   UOP_SaveXMM128Big,
0040   UOP_PushMachFrame,
0041   // The following set of unwind opcodes is for ARM64.  They are documented at
0042   // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
0043   UOP_AllocMedium,
0044   UOP_SaveR19R20X,
0045   UOP_SaveFPLRX,
0046   UOP_SaveFPLR,
0047   UOP_SaveReg,
0048   UOP_SaveRegX,
0049   UOP_SaveRegP,
0050   UOP_SaveRegPX,
0051   UOP_SaveLRPair,
0052   UOP_SaveFReg,
0053   UOP_SaveFRegX,
0054   UOP_SaveFRegP,
0055   UOP_SaveFRegPX,
0056   UOP_SetFP,
0057   UOP_AddFP,
0058   UOP_Nop,
0059   UOP_End,
0060   UOP_SaveNext,
0061   UOP_TrapFrame,
0062   UOP_Context,
0063   UOP_ECContext,
0064   UOP_ClearUnwoundToCall,
0065   UOP_PACSignLR,
0066   UOP_SaveAnyRegI,
0067   UOP_SaveAnyRegIP,
0068   UOP_SaveAnyRegD,
0069   UOP_SaveAnyRegDP,
0070   UOP_SaveAnyRegQ,
0071   UOP_SaveAnyRegQP,
0072   UOP_SaveAnyRegIX,
0073   UOP_SaveAnyRegIPX,
0074   UOP_SaveAnyRegDX,
0075   UOP_SaveAnyRegDPX,
0076   UOP_SaveAnyRegQX,
0077   UOP_SaveAnyRegQPX,
0078 
0079   // The following set of unwind opcodes is for ARM.  They are documented at
0080   // https://docs.microsoft.com/en-us/cpp/build/arm-exception-handling
0081 
0082   // Stack allocations use UOP_AllocSmall, UOP_AllocLarge from above, plus
0083   // the following. AllocSmall, AllocLarge and AllocHuge represent a 16 bit
0084   // instruction, while the WideAlloc* opcodes represent a 32 bit instruction.
0085   // Small can represent a stack offset of 0x7f*4 (252) bytes, Medium can
0086   // represent up to 0x3ff*4 (4092) bytes, Large up to 0xffff*4 (262140) bytes,
0087   // and Huge up to 0xffffff*4 (67108860) bytes.
0088   UOP_AllocHuge,
0089   UOP_WideAllocMedium,
0090   UOP_WideAllocLarge,
0091   UOP_WideAllocHuge,
0092 
0093   UOP_WideSaveRegMask,
0094   UOP_SaveSP,
0095   UOP_SaveRegsR4R7LR,
0096   UOP_WideSaveRegsR4R11LR,
0097   UOP_SaveFRegD8D15,
0098   UOP_SaveRegMask,
0099   UOP_SaveLR,
0100   UOP_SaveFRegD0D15,
0101   UOP_SaveFRegD16D31,
0102   // Using UOP_Nop from above
0103   UOP_WideNop,
0104   // Using UOP_End from above
0105   UOP_EndNop,
0106   UOP_WideEndNop,
0107   // A custom unspecified opcode, consisting of one or more bytes. This
0108   // allows producing opcodes in the implementation defined/reserved range.
0109   UOP_Custom,
0110 };
0111 
0112 /// UnwindCode - This union describes a single operation in a function prolog,
0113 /// or part thereof.
0114 union UnwindCode {
0115   struct {
0116     uint8_t CodeOffset;
0117     uint8_t UnwindOpAndOpInfo;
0118   } u;
0119   support::ulittle16_t FrameOffset;
0120 
0121   uint8_t getUnwindOp() const {
0122     return u.UnwindOpAndOpInfo & 0x0F;
0123   }
0124   uint8_t getOpInfo() const {
0125     return (u.UnwindOpAndOpInfo >> 4) & 0x0F;
0126   }
0127   /// Gets the offset for an UOP_Epilog unwind code.
0128   uint32_t getEpilogOffset() const {
0129     assert(getUnwindOp() == UOP_Epilog);
0130     return (getOpInfo() << 8) | static_cast<uint32_t>(u.CodeOffset);
0131   }
0132 };
0133 
0134 enum {
0135   /// UNW_ExceptionHandler - Specifies that this function has an exception
0136   /// handler.
0137   UNW_ExceptionHandler = 0x01,
0138   /// UNW_TerminateHandler - Specifies that this function has a termination
0139   /// handler.
0140   UNW_TerminateHandler = 0x02,
0141   /// UNW_ChainInfo - Specifies that this UnwindInfo structure is chained to
0142   /// another one.
0143   UNW_ChainInfo = 0x04
0144 };
0145 
0146 /// RuntimeFunction - An entry in the table of functions with unwind info.
0147 struct RuntimeFunction {
0148   support::ulittle32_t StartAddress;
0149   support::ulittle32_t EndAddress;
0150   support::ulittle32_t UnwindInfoOffset;
0151 };
0152 
0153 /// UnwindInfo - An entry in the exception table.
0154 struct UnwindInfo {
0155   uint8_t VersionAndFlags;
0156   uint8_t PrologSize;
0157   uint8_t NumCodes;
0158   uint8_t FrameRegisterAndOffset;
0159   UnwindCode UnwindCodes[1];
0160 
0161   uint8_t getVersion() const {
0162     return VersionAndFlags & 0x07;
0163   }
0164   uint8_t getFlags() const {
0165     return (VersionAndFlags >> 3) & 0x1f;
0166   }
0167   uint8_t getFrameRegister() const {
0168     return FrameRegisterAndOffset & 0x0f;
0169   }
0170   uint8_t getFrameOffset() const {
0171     return (FrameRegisterAndOffset >> 4) & 0x0f;
0172   }
0173 
0174   // The data after unwindCodes depends on flags.
0175   // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows
0176   // the address of the language-specific exception handler.
0177   // If UNW_ChainInfo is set then follows a RuntimeFunction which defines
0178   // the chained unwind info.
0179   // For more information please see MSDN at:
0180   // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx
0181 
0182   /// Return pointer to language specific data part of UnwindInfo.
0183   void *getLanguageSpecificData() {
0184     return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]);
0185   }
0186 
0187   /// Return pointer to language specific data part of UnwindInfo.
0188   const void *getLanguageSpecificData() const {
0189     return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes + 1) & ~1]);
0190   }
0191 
0192   /// Return image-relative offset of language-specific exception handler.
0193   uint32_t getLanguageSpecificHandlerOffset() const {
0194     return *reinterpret_cast<const support::ulittle32_t *>(
0195                getLanguageSpecificData());
0196   }
0197 
0198   /// Set image-relative offset of language-specific exception handler.
0199   void setLanguageSpecificHandlerOffset(uint32_t offset) {
0200     *reinterpret_cast<support::ulittle32_t *>(getLanguageSpecificData()) =
0201         offset;
0202   }
0203 
0204   /// Return pointer to exception-specific data.
0205   void *getExceptionData() {
0206     return reinterpret_cast<void *>(reinterpret_cast<uint32_t *>(
0207                                                   getLanguageSpecificData())+1);
0208   }
0209 
0210   /// Return pointer to chained unwind info.
0211   RuntimeFunction *getChainedFunctionEntry() {
0212     return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
0213   }
0214 
0215   /// Return pointer to chained unwind info.
0216   const RuntimeFunction *getChainedFunctionEntry() const {
0217     return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificData());
0218   }
0219 };
0220 
0221 
0222 } // End of namespace Win64EH
0223 } // End of namespace llvm
0224 
0225 #endif