| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #pragma once
- enum UnwindCode;
- class UnwindInfoManager
- {
- public:
- UnwindInfoManager() :
- func(NULL),
- fragmentStart(NULL),
- fragmentLength(0),
- epilogEndOffset(0),
- prologOffset(0),
- savedRegMask(0),
- savedDoubleRegMask(0),
- homedParamCount(0),
- stackDepth(0),
- hasCalls(false),
- prologLabelId(0),
- epilogEndLabelId(0),
- pdataArray(NULL),
- xdataArray(NULL)
- {
- }
- void Init(Func * func) { this->func = func; }
- void EmitUnwindInfo(PBYTE funcStart, DWORD size, CustomHeap::Allocation* allocation) { __debugbreak(); }
- DWORD EmitLongUnwindInfoChunk(DWORD remainingLength) { __debugbreak(); }
- void SetFunc(Func *func)
- {
- Assert(this->func == NULL);
- this->func = func;
- }
- Func * GetFunc() const
- {
- return this->func;
- }
- void SetFragmentStart(PBYTE pStart)
- {
- this->fragmentStart = pStart;
- }
- PBYTE GetFragmentStart() const
- {
- return this->fragmentStart;
- }
- void SetEpilogEndOffset(DWORD offset)
- {
- Assert(this->epilogEndOffset == 0);
- this->epilogEndOffset = offset;
- }
- DWORD GetEpilogEndOffset() const
- {
- return this->epilogEndOffset;
- }
- void SetPrologOffset(DWORD offset)
- {
- Assert(this->prologOffset == 0);
- this->prologOffset = offset;
- }
- DWORD GetPrologOffset() const
- {
- return this->prologOffset;
- }
- void SetFragmentLength(DWORD length)
- {
- this->fragmentLength = length;
- }
- DWORD GetFragmentLength() const
- {
- return this->fragmentLength;
- }
- void SetHomedParamCount(BYTE count)
- {
- Assert(this->homedParamCount == 0);
- this->homedParamCount = count;
- }
- DWORD GetHomedParamCount() const
- {
- return this->homedParamCount;
- }
- void SetStackDepth(DWORD depth)
- {
- Assert(this->stackDepth == 0);
- this->stackDepth = depth;
- }
- DWORD GetStackDepth() const
- {
- return this->stackDepth;
- }
- void SetHasCalls(bool has)
- {
- this->hasCalls = has;
- }
- bool GetHasCalls() const
- {
- return this->hasCalls;
- }
- void SetPrologStartLabel(DWORD id)
- {
- Assert(this->prologLabelId == 0);
- this->prologLabelId = id;
- }
- DWORD GetPrologStartLabel() const
- {
- return this->prologLabelId;
- }
- void SetEpilogEndLabel(DWORD id)
- {
- Assert(this->epilogEndLabelId == 0);
- this->epilogEndLabelId = id;
- }
- DWORD GetEpilogEndLabel() const
- {
- return this->epilogEndLabelId;
- }
- bool GetHasChkStk() const { __debugbreak(); return 0; }
- DWORD GetPDataCount(DWORD length) { __debugbreak(); return 0; }
- void SetSavedReg(BYTE reg) { __debugbreak(); }
- DWORD ClearSavedReg(DWORD mask, BYTE reg) const { __debugbreak(); return 0; }
- void SetDoubleSavedRegList(DWORD doubleRegMask) { __debugbreak(); }
- DWORD GetDoubleSavedRegList() const { __debugbreak(); return 0; }
- static BYTE GetLastSavedReg(DWORD mask) { __debugbreak(); return 0; }
- static BYTE GetFirstSavedReg(DWORD mask) { __debugbreak(); return 0; }
- private:
- Func * func;
- PBYTE fragmentStart;
- RUNTIME_FUNCTION* pdataArray;
- BYTE* xdataArray;
- DWORD fragmentLength;
- DWORD prologOffset;
- DWORD prologLabelId;
- DWORD epilogEndLabelId;
- DWORD epilogEndOffset;
- DWORD savedRegMask;
- DWORD savedDoubleRegMask;
- DWORD stackDepth;
- BYTE homedParamCount;
- bool hasCalls;
- bool fragmentHasProlog;
- bool fragmentHasEpilog;
- void EmitPdata();
- bool CanEmitPackedPdata() const;
- void EncodePackedUnwindData();
- void EncodeExpandedUnwindData();
- BYTE * GetBaseAddress();
- bool IsPdataPacked(const DWORD *pdata) const;
- bool IsR4SavedRegRange(bool saveR11) const;
- static bool IsR4SavedRegRange(DWORD saveRegMask);
- DWORD XdataTemplate(UnwindCode op) const;
- DWORD XdataLength(UnwindCode op) const;
- DWORD EmitXdataStackAlloc(BYTE xData[], DWORD byte, DWORD stack);
- DWORD EmitXdataHomeParams(BYTE xData[], DWORD byte);
- DWORD EmitXdataRestoreRegs(BYTE xData[], DWORD byte, DWORD savedRegMask, bool restoreLR);
- DWORD EmitXdataRestoreDoubleRegs(BYTE xData[], DWORD byte, DWORD savedDoubleRegMask);
- DWORD EmitXdataIndirReturn(BYTE xData[], DWORD byte);
- DWORD EmitXdataNop32(BYTE xData[], DWORD byte);
- DWORD EmitXdataNop16(BYTE xData[], DWORD byte);
- DWORD EmitXdataEnd(BYTE xData[], DWORD byte);
- DWORD EmitXdataEndPlus16(BYTE xData[], DWORD byte);
- DWORD EmitXdataLocalsPointer(BYTE xData[], DWORD byte, BYTE regEncode);
- DWORD RelativeRegEncoding(RegNum reg, RegNum baseReg) const;
- DWORD WriteXdataBytes(BYTE xdata[], DWORD byte, DWORD encoding, DWORD length);
- // Constants defined in the ABI.
- static const DWORD MaxPackedPdataFuncLength = 0xFFE;
- static const DWORD MaxPackedPdataStackDepth = 0xFCC;
- static const DWORD PackedPdataFlagMask = 3;
- static const DWORD ExpandedPdataFlag = 0;
- // Function length is required to have only these bits set.
- static const DWORD PackedFuncLengthMask = 0xFFE;
- // Bit offset of length within pdata dword, combined with right-shift of encoded length.
- static const DWORD PackedFuncLengthShift = 1;
- static const DWORD PackedNoPrologBits = 2;
- static const DWORD PackedNormalFuncBits = 1;
- static const DWORD PackedNonLeafRetBits = 0;
- static const DWORD PackedLeafRetBits = (1 << 13);
- static const DWORD PackedNoEpilogBits = (3 << 13);
- // C (frame chaining) and L (save LR) bits.
- static const DWORD PackedNonLeafFunctionBits = (1 << 20) | (1 << 21);
- static const DWORD PackedHomedParamsBit = (1 << 15);
- static const DWORD PackedRegShift = 16;
- static const DWORD PackedRegMask = 7;
- // Indicate no saved regs with a Reg field of 0x111 and the R bit set.
- static const DWORD PackedNoSavedRegsBits = (7 << PackedRegShift) | (1 << 19);
- // Stack depth is required to have only these bits set.
- static const DWORD PackedStackDepthMask = 0xFFC;
- // Bit offset of stack depth within pdata dword, combined with right-shift of encoded value.
- static const DWORD PackedStackDepthShift = 20;
- static const DWORD MaxXdataFuncLength = 0x7FFFE;
- static const DWORD XdataFuncLengthMask = 0x7FFFE;
- static const DWORD XdataFuncLengthAdjust = 1;
- static const DWORD XdataSingleEpilogShift = 21;
- static const DWORD XdataFuncFragmentShift = 22;
- static const DWORD XdataEpilogCountShift = 23;
- static const DWORD MaxXdataEpilogCount = 0x1F;
- static const DWORD MaxXdataDwordCount = 0xF;
- static const DWORD XdataDwordCountShift = 28;
- public:
- // Xdata constants.
- static const DWORD MaxXdataBytes = 40; //buffer of 4 for any future additions
- //
- // 28 == 4 (header DWORD) +
- // (4 (max stack alloc code) +
- // 1 (locals pointer setup) +
- // 5 (NOP for _chkstk case) +
- // 1 (double reg saves) +
- // 2 (reg saves) +
- // 1 (r11 setup) +
- // 2 (r11,lr saves) +
- // 1 (home params) +
- // 1 (NOP) +
- // 1 (end prolog) +
- // 4 (max stack alloc code, in case of locals pointer setup) +
- // 1 (double reg saves) +
- // 2 (reg saves) +
- // 2 (r11 save) +
- // 2 (indir return) +
- // 1 (end epilog)) rounded up to a DWORD boundary
- };
|