コード例 #1
0
        private NativeParser GetParserForBucket(uint bucket, out uint endOffset)
        {
            uint start, end;

            if (_entryIndexSize == 0)
            {
                int bucketOffset = (int)(_baseOffset + bucket);
                start = NativeReader.ReadByte(_image, ref bucketOffset);
                end   = NativeReader.ReadByte(_image, ref bucketOffset);
            }
            else if (_entryIndexSize == 1)
            {
                int bucketOffset = (int)(_baseOffset + 2 * bucket);
                start = NativeReader.ReadUInt16(_image, ref bucketOffset);
                end   = NativeReader.ReadUInt16(_image, ref bucketOffset);
            }
            else
            {
                int bucketOffset = (int)(_baseOffset + 4 * bucket);
                start = NativeReader.ReadUInt32(_image, ref bucketOffset);
                end   = NativeReader.ReadUInt32(_image, ref bucketOffset);
            }

            endOffset = end + _baseOffset;
            return(new NativeParser(_image, _baseOffset + start));
        }
コード例 #2
0
ファイル: UnwindInfo.cs プロジェクト: hsharber/coreclr
        public UnwindInfo(byte[] image, int offset)
        {
            byte versionAndFlags = NativeReader.ReadByte(image, ref offset);

            Version            = (byte)(versionAndFlags & 7);
            Flags              = (byte)(versionAndFlags >> 3);
            SizeOfProlog       = NativeReader.ReadByte(image, ref offset);
            CountOfUnwindCodes = NativeReader.ReadByte(image, ref offset);
            byte frameRegisterAndOffset = NativeReader.ReadByte(image, ref offset);

            FrameRegister = (Amd64Registers)(frameRegisterAndOffset & 15);
            FrameOffset   = (byte)(frameRegisterAndOffset >> 4);

            UnwindCode = new UnwindCode[CountOfUnwindCodes];
            for (int i = 0; i < CountOfUnwindCodes; i++)
            {
                UnwindCode[i] = new UnwindCode(image, ref offset);
            }

            PersonalityRoutineRVA = NativeReader.ReadUInt32(image, ref offset);

            Size = _offsetofUnwindCode + CountOfUnwindCodes * _sizeofUnwindCode;
            int alignmentPad = ((Size + sizeof(int) - 1) & ~(sizeof(int) - 1)) - Size;

            Size += (alignmentPad + sizeof(uint));
        }
コード例 #3
0
        /// <summary>
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/zap/zapcode.cpp">ZapUnwindData::Save</a>
        /// </summary>
        public UnwindInfo(byte[] image, int offset)
        {
            byte versionAndFlags = NativeReader.ReadByte(image, ref offset);

            Version            = (byte)(versionAndFlags & 7);
            Flags              = (byte)(versionAndFlags >> 3);
            SizeOfProlog       = NativeReader.ReadByte(image, ref offset);
            CountOfUnwindCodes = NativeReader.ReadByte(image, ref offset);
            byte frameRegisterAndOffset = NativeReader.ReadByte(image, ref offset);

            FrameRegister = (Registers)(frameRegisterAndOffset & 15);
            FrameOffset   = (byte)(frameRegisterAndOffset >> 4);

            UnwindCodes = new List <UnwindCode>(CountOfUnwindCodes);
            CodeOffsetToUnwindCodeIndex = new Dictionary <int, int>();
            int frameOffset       = FrameOffset;
            int sizeOfUnwindCodes = CountOfUnwindCodes * _sizeofUnwindCode;
            int endOffset         = offset + sizeOfUnwindCodes;

            while (offset < endOffset)
            {
                UnwindCode unwindCode = new UnwindCode(image, ref frameOffset, ref offset);
                CodeOffsetToUnwindCodeIndex.Add(unwindCode.CodeOffset, UnwindCodes.Count);
                UnwindCodes.Add(unwindCode);
            }

            Size = _offsetofUnwindCode + sizeOfUnwindCodes;
            int alignmentPad = -Size & 3;

            Size += alignmentPad + sizeof(uint);

            // Personality routine RVA must be at 4-aligned address
            offset += alignmentPad;
            PersonalityRoutineRVA = NativeReader.ReadUInt32(image, ref offset);
        }
コード例 #4
0
        public UnwindCode(byte[] image, int index, ref int offset)
        {
            Index = index;

            int off = offset;

            CodeOffset = NativeReader.ReadByte(image, ref off);
            byte op = NativeReader.ReadByte(image, ref off);

            UnwindOp = (UnwindOpCodes)(op & 15);
            OpInfo   = (byte)(op >> 4);

            OffsetLow  = CodeOffset;
            OffsetHigh = OpInfo;

            FrameOffset     = NativeReader.ReadUInt16(image, ref offset);
            NextFrameOffset = -1;

            if (UnwindOp == UnwindOpCodes.UWOP_ALLOC_LARGE)
            {
                uint codedSize;
                if (OpInfo == 0)
                {
                    codedSize = NativeReader.ReadUInt16(image, ref offset);
                }
                else if (OpInfo == 1)
                {
                    codedSize = NativeReader.ReadUInt32(image, ref offset);
                }
            }

            IsOpInfo = false;
        }
コード例 #5
0
        /// <summary>
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/zap/zapcode.cpp">ZapUnwindData::Save</a>
        /// </summary>
        public UnwindInfo(byte[] image, int offset)
        {
            byte versionAndFlags = NativeReader.ReadByte(image, ref offset);

            Version            = (byte)(versionAndFlags & 7);
            Flags              = (byte)(versionAndFlags >> 3);
            SizeOfProlog       = NativeReader.ReadByte(image, ref offset);
            CountOfUnwindCodes = NativeReader.ReadByte(image, ref offset);
            byte frameRegisterAndOffset = NativeReader.ReadByte(image, ref offset);

            FrameRegister = (Registers)(frameRegisterAndOffset & 15);
            FrameOffset   = (byte)(frameRegisterAndOffset >> 4);

            UnwindCodeArray = new UnwindCode[CountOfUnwindCodes];
            UnwindCodes     = new Dictionary <int, UnwindCode>();
            for (int i = 0; i < CountOfUnwindCodes; i++)
            {
                UnwindCodeArray[i] = new UnwindCode(image, i, ref offset);
            }
            for (int i = 0; i < CountOfUnwindCodes; i++)
            {
                ParseUnwindCode(ref i);
                Debug.Assert(!UnwindCodes.ContainsKey(UnwindCodeArray[i].CodeOffset));
                UnwindCodes.Add(UnwindCodeArray[i].CodeOffset, UnwindCodeArray[i]);
            }

            Size = _offsetofUnwindCode + CountOfUnwindCodes * _sizeofUnwindCode;
            int alignmentPad = -Size & 3;

            Size += alignmentPad + sizeof(uint);

            // Personality routine RVA must be at 4-aligned address
            offset += alignmentPad;
            PersonalityRoutineRVA = NativeReader.ReadUInt32(image, ref offset);
        }
コード例 #6
0
        public byte GetByte()
        {
            int  off = (int)Offset;
            byte val = NativeReader.ReadByte(_image, ref off);

            Offset += 1;
            return(val);
        }
コード例 #7
0
ファイル: UnwindInfo.cs プロジェクト: hsharber/coreclr
        public UnwindCode(byte[] image, ref int offset)
        {
            int off = offset;

            CodeOffset = NativeReader.ReadByte(image, ref off);
            byte op = NativeReader.ReadByte(image, ref off);

            UnwindOp = (UnwindOpCodes)(op & 15);
            OpInfo   = (byte)(op >> 4);

            OffsetLow  = CodeOffset;
            OffsetHigh = OpInfo;

            FrameOffset = NativeReader.ReadUInt16(image, ref offset);
        }
コード例 #8
0
        public UnwindCode(byte[] image, int index, ref int offset)
        {
            Index = index;

            int off = offset;

            CodeOffset = NativeReader.ReadByte(image, ref off);
            byte op = NativeReader.ReadByte(image, ref off);

            UnwindOp = (UnwindOpCodes)(op & 15);
            OpInfo   = (byte)(op >> 4);

            OffsetLow  = CodeOffset;
            OffsetHigh = OpInfo;

            FrameOffset     = NativeReader.ReadUInt16(image, ref offset);
            NextFrameOffset = -1;

            IsOpInfo = false;
        }
コード例 #9
0
        /// <summary>
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/zap/zapcode.cpp">ZapUnwindData::Save</a>
        /// </summary>
        public UnwindInfo(byte[] image, int offset)
        {
            byte versionAndFlags = NativeReader.ReadByte(image, ref offset);

            Version            = (byte)(versionAndFlags & 7);
            Flags              = (byte)(versionAndFlags >> 3);
            SizeOfProlog       = NativeReader.ReadByte(image, ref offset);
            CountOfUnwindCodes = NativeReader.ReadByte(image, ref offset);
            byte frameRegisterAndOffset = NativeReader.ReadByte(image, ref offset);

            FrameRegister = (Registers)(frameRegisterAndOffset & 15);
            FrameOffset   = (byte)(frameRegisterAndOffset >> 4);

            UnwindCodeArray = new UnwindCode[CountOfUnwindCodes];
            UnwindCodes     = new Dictionary <int, List <UnwindCode> >();
            for (int i = 0; i < CountOfUnwindCodes; i++)
            {
                UnwindCodeArray[i] = new UnwindCode(image, i, ref offset);
            }
            for (int i = 0; i < CountOfUnwindCodes; i++)
            {
                ParseUnwindCode(ref i);
                if (!UnwindCodes.ContainsKey(UnwindCodeArray[i].CodeOffset))
                {
                    UnwindCodes[UnwindCodeArray[i].CodeOffset] = new List <UnwindCode>();
                }
                UnwindCodes[UnwindCodeArray[i].CodeOffset].Add(UnwindCodeArray[i]);
            }

            PersonalityRoutineRVA = NativeReader.ReadUInt32(image, ref offset);

            Size = _offsetofUnwindCode + CountOfUnwindCodes * _sizeofUnwindCode;
            int alignmentPad = ((Size + sizeof(int) - 1) & ~(sizeof(int) - 1)) - Size;

            Size += (alignmentPad + sizeof(uint));
        }
コード例 #10
0
        /// <summary>
        /// Unwinde code parsing is based on <a href="https://github.com/dotnet/coreclr/blob/master/src/jit/unwindamd64.cpp">src\jit\unwindamd64.cpp</a> DumpUnwindInfo
        /// </summary>
        public UnwindCode(byte[] image, ref int frameOffset, ref int offset)
        {
            CodeOffset = NativeReader.ReadByte(image, ref offset);
            byte op = NativeReader.ReadByte(image, ref offset);

            UnwindOp = (UnwindOpCodes)(op & 15);
            OpInfo   = (byte)(op >> 4);

            OffsetLow  = CodeOffset;
            OffsetHigh = OpInfo;

            FrameOffset = frameOffset;

            switch (UnwindOp)
            {
            case UnwindOpCodes.UWOP_PUSH_NONVOL:
                OpInfoStr = $"{(Registers)OpInfo}({OpInfo})";
                break;

            case UnwindOpCodes.UWOP_ALLOC_LARGE:
                OpInfoStr = $"{OpInfo} - ";
                if (OpInfo == 0)
                {
                    OpInfoStr      += "Scaled small";
                    NextFrameOffset = 8 * NativeReader.ReadUInt16(image, ref offset);
                }
                else if (OpInfo == 1)
                {
                    OpInfoStr += "Unscaled large";
                    uint nextOffset = NativeReader.ReadUInt16(image, ref offset);
                    NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset);
                }
                else
                {
                    throw new BadImageFormatException();
                }
                break;

            case UnwindOpCodes.UWOP_ALLOC_SMALL:
                int opInfo = OpInfo * 8 + 8;
                OpInfoStr = $"{opInfo}";
                break;

            case UnwindOpCodes.UWOP_SET_FPREG:
                OpInfoStr = $"Unused({OpInfo})";
                break;

            case UnwindOpCodes.UWOP_SET_FPREG_LARGE:
            {
                OpInfoStr = $"Unused({OpInfo})";
                uint nextOffset = NativeReader.ReadUInt16(image, ref offset);
                nextOffset      = ((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset);
                NextFrameOffset = (int)nextOffset * 16;
                if ((NextFrameOffset & 0xF0000000) != 0)
                {
                    throw new BadImageFormatException("Warning: Illegal unwindInfo unscaled offset: too large");
                }
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_NONVOL:
            {
                OpInfoStr       = $"{(Registers)OpInfo}({OpInfo})";
                NextFrameOffset = NativeReader.ReadUInt16(image, ref offset) * 8;
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_NONVOL_FAR:
            {
                OpInfoStr = $"{(Registers)OpInfo}({OpInfo})";
                uint nextOffset = NativeReader.ReadUInt16(image, ref offset);
                NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset);
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_XMM128:
            {
                OpInfoStr       = $"XMM{OpInfo}({OpInfo})";
                NextFrameOffset = (int)NativeReader.ReadUInt16(image, ref offset) * 16;
            }
            break;

            case UnwindOpCodes.UWOP_SAVE_XMM128_FAR:
            {
                OpInfoStr = $"XMM{OpInfo}({OpInfo})";
                uint nextOffset = NativeReader.ReadUInt16(image, ref offset);
                NextFrameOffset = (int)((uint)(NativeReader.ReadUInt16(image, ref offset) << 16) | nextOffset);
            }
            break;

            default:
                throw new NotImplementedException(UnwindOp.ToString());
            }

            NextFrameOffset = frameOffset;
        }
コード例 #11
0
        public bool TryGetAt(byte[] image, uint index, ref int pOffset)
        {
            if (index >= _nElements)
            {
                return(false);
            }

            uint offset = 0;

            if (_entryIndexSize == 0)
            {
                int i = (int)(_baseOffset + (index / _blockSize));
                offset = NativeReader.ReadByte(image, ref i);
            }
            else if (_entryIndexSize == 1)
            {
                int i = (int)(_baseOffset + 2 * (index / _blockSize));
                offset = NativeReader.ReadUInt16(image, ref i);
            }
            else
            {
                int i = (int)(_baseOffset + 4 * (index / _blockSize));
                offset = NativeReader.ReadUInt32(image, ref i);
            }
            offset += _baseOffset;

            for (uint bit = _blockSize >> 1; bit > 0; bit >>= 1)
            {
                uint val     = 0;
                uint offset2 = NativeReader.DecodeUnsigned(image, offset, ref val);
                if ((index & bit) != 0)
                {
                    if ((val & 2) != 0)
                    {
                        offset = offset + (val >> 2);
                        continue;
                    }
                }
                else
                {
                    if ((val & 1) != 0)
                    {
                        offset = offset2;
                        continue;
                    }
                }

                // Not found
                if ((val & 3) == 0)
                {
                    // Matching special leaf node?
                    if ((val >> 2) == (index & (_blockSize - 1)))
                    {
                        offset = offset2;
                        break;
                    }
                }
                return(false);
            }
            pOffset = (int)offset;
            return(true);
        }