X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FWin64EH.h;h=f6c492794875cccd07acef8886fd49782af7e17c;hb=8143b4da3f8df2506d768f2833a2888545489853;hp=54ed68c52f27ba15f49c0cee6b48a04e321e094e;hpb=c36849c4037a0a79945e9b03a4a31e81dbdfbece;p=oota-llvm.git diff --git a/include/llvm/Support/Win64EH.h b/include/llvm/Support/Win64EH.h index 54ed68c52f2..f6c49279487 100644 --- a/include/llvm/Support/Win64EH.h +++ b/include/llvm/Support/Win64EH.h @@ -16,11 +16,12 @@ #ifndef LLVM_SUPPORT_WIN64EH_H #define LLVM_SUPPORT_WIN64EH_H +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Endian.h" + namespace llvm { namespace Win64EH { -extern "C" { - /// UnwindOpcodes - Enumeration whose values specify a single operation in /// the prolog of a function. enum UnwindOpcodes { @@ -30,7 +31,7 @@ enum UnwindOpcodes { UOP_SetFPReg, UOP_SaveNonVol, UOP_SaveNonVolBig, - UOP_SaveXMM128, + UOP_SaveXMM128 = 8, UOP_SaveXMM128Big, UOP_PushMachFrame }; @@ -39,11 +40,17 @@ enum UnwindOpcodes { /// or part thereof. union UnwindCode { struct { - uint8_t codeOffset; - uint8_t unwindOp:4, - opInfo:4; - }; - uint16_t frameOffset; + uint8_t CodeOffset; + uint8_t UnwindOpAndOpInfo; + } u; + support::ulittle16_t FrameOffset; + + uint8_t getUnwindOp() const { + return u.UnwindOpAndOpInfo & 0x0F; + } + uint8_t getOpInfo() const { + return (u.UnwindOpAndOpInfo >> 4) & 0x0F; + } }; enum { @@ -58,41 +65,81 @@ enum { UNW_ChainInfo = 0x04 }; +/// RuntimeFunction - An entry in the table of functions with unwind info. +struct RuntimeFunction { + support::ulittle32_t StartAddress; + support::ulittle32_t EndAddress; + support::ulittle32_t UnwindInfoOffset; +}; + /// UnwindInfo - An entry in the exception table. struct UnwindInfo { - uint8_t version:3, - flags:5; - uint8_t prologSize; - uint8_t numCodes; - uint8_t frameRegister:4, - frameOffset:4; - UnwindCode unwindCodes[1]; + uint8_t VersionAndFlags; + uint8_t PrologSize; + uint8_t NumCodes; + uint8_t FrameRegisterAndOffset; + UnwindCode UnwindCodes[1]; + + uint8_t getVersion() const { + return VersionAndFlags & 0x07; + } + uint8_t getFlags() const { + return (VersionAndFlags >> 3) & 0x1f; + } + uint8_t getFrameRegister() const { + return FrameRegisterAndOffset & 0x0f; + } + uint8_t getFrameOffset() const { + return (FrameRegisterAndOffset >> 4) & 0x0f; + } + + // The data after unwindCodes depends on flags. + // If UNW_ExceptionHandler or UNW_TerminateHandler is set then follows + // the address of the language-specific exception handler. + // If UNW_ChainInfo is set then follows a RuntimeFunction which defines + // the chained unwind info. + // For more information please see MSDN at: + // http://msdn.microsoft.com/en-us/library/ddssxxy8.aspx + + /// \brief Return pointer to language specific data part of UnwindInfo. + void *getLanguageSpecificData() { + return reinterpret_cast(&UnwindCodes[(NumCodes+1) & ~1]); + } + + /// \brief Return pointer to language specific data part of UnwindInfo. + const void *getLanguageSpecificData() const { + return reinterpret_cast(&UnwindCodes[(NumCodes + 1) & ~1]); + } + + /// \brief Return image-relative offset of language-specific exception handler. + uint32_t getLanguageSpecificHandlerOffset() const { + return *reinterpret_cast( + getLanguageSpecificData()); + } + + /// \brief Set image-relative offset of language-specific exception handler. + void setLanguageSpecificHandlerOffset(uint32_t offset) { + *reinterpret_cast(getLanguageSpecificData()) = + offset; + } + + /// \brief Return pointer to exception-specific data. + void *getExceptionData() { + return reinterpret_cast(reinterpret_cast( + getLanguageSpecificData())+1); + } + + /// \brief Return pointer to chained unwind info. + RuntimeFunction *getChainedFunctionEntry() { + return reinterpret_cast(getLanguageSpecificData()); + } + + /// \brief Return pointer to chained unwind info. + const RuntimeFunction *getChainedFunctionEntry() const { + return reinterpret_cast(getLanguageSpecificData()); + } }; -inline UnwindCode &getUnwindCodeEntry(UnwindInfo &info, uint32_t index) { - return info.unwindCodes[index]; -} -inline void *getLanguageSpecificData(UnwindInfo &info) { - return reinterpret_cast(&getUnwindCodeEntry(info,info.numCodes+1)&~1); -} -inline uint64_t getLanguageSpecificHandlerOffset(UnwindInfo &info) { - return *reinterpret_cast(getLangaugeSpecificData(info)); -} -inline void setLanguageSpecificHandlerOffset(UnwindInfo &info, uint64_t offset){ - *reinterpret_cast(getLanguageSpecificData(info)) = offset; -} -inline uint64_t getChainedFunctionEntryOffset(UnwindInfo &info) { - return *reinterpret_cast(getLanguageSpecificData(info)); -} -inline void setChainedFunctionEntryOffset(UnwindInfo &info, uint64_t offset) { - *reinterpret_cast(getLanguageSpecificData(info)) = offset; -} -inline void *getExceptionData(UnwindInfo &info) { - return reinterpret_cast(reinterpret_cast( - getLanguageSpecificData(info))+1); -} - -} // End of extern "C" } // End of namespace Win64EH } // End of namespace llvm