Пример #1
0
        public DebugInfo(byte[] image, int offset, Machine machine)
        {
            _machine = machine;

            // Get the id of the runtime function from the NativeArray
            uint lookback        = 0;
            uint debugInfoOffset = NativeReader.DecodeUnsigned(image, (uint)offset, ref lookback);

            if (lookback != 0)
            {
                System.Diagnostics.Debug.Assert(0 < lookback && lookback < offset);
                debugInfoOffset = (uint)offset - lookback;
            }

            NibbleReader reader             = new NibbleReader(image, (int)debugInfoOffset);
            uint         boundsByteCount    = reader.ReadUInt();
            uint         variablesByteCount = reader.ReadUInt();
            int          boundsOffset       = reader.GetNextByteOffset();
            int          variablesOffset    = (int)(boundsOffset + boundsByteCount);

            if (boundsByteCount > 0)
            {
                ParseBounds(image, boundsOffset);
            }

            if (variablesByteCount > 0)
            {
                ParseNativeVarInfo(image, variablesOffset);
            }
        }
Пример #2
0
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            int iiOffset             = _startOffset;
            int sizeOfInlineIndex    = NativeReader.ReadInt32(_r2r.Image, ref iiOffset);
            int inlineIndexEndOffset = iiOffset + sizeOfInlineIndex;

            while (iiOffset < inlineIndexEndOffset)
            {
                int inlineeRid     = NativeReader.ReadInt32(_r2r.Image, ref iiOffset);
                int inlinersOffset = NativeReader.ReadInt32(_r2r.Image, ref iiOffset);
                sb.AppendLine($"Inliners for inlinee {RidToMethodDef(inlineeRid):X8}:");
                var  inlinersReader  = new NibbleReader(_r2r.Image, inlineIndexEndOffset + inlinersOffset);
                uint sameModuleCount = inlinersReader.ReadUInt();

                int baseRid = 0;
                for (uint i = 0; i < sameModuleCount; i++)
                {
                    int currentRid = baseRid + (int)inlinersReader.ReadUInt();
                    sb.AppendLine($"  {RidToMethodDef(currentRid):X8}");
                    baseRid = currentRid;
                }
            }

            return(sb.ToString());
        }
Пример #3
0
        private int ReadEncodedStackOffset(NibbleReader reader)
        {
            int offset = reader.ReadInt();

            if (_machine == Machine.I386)
            {
                offset *= 4; // sizeof(DWORD)
            }

            return(offset);
        }
Пример #4
0
        private void EnsureFixupCells()
        {
            if (_fixupCells != null)
            {
                return;
            }
            if (!_fixupOffset.HasValue)
            {
                return;
            }
            _fixupCells = new List <FixupCell>();
            NibbleReader reader = new NibbleReader(_readyToRunReader.Image, _fixupOffset.Value);

            // The following algorithm has been loosely ported from CoreCLR,
            // src\vm\ceeload.inl, BOOL Module::FixupDelayListAux
            uint curTableIndex = reader.ReadUInt();

            while (true)
            {
                uint fixupIndex = reader.ReadUInt(); // Accumulate the real rva from the delta encoded rva

                while (true)
                {
                    ReadyToRunImportSection importSection            = _readyToRunReader.ImportSections[(int)curTableIndex];
                    ReadyToRunImportSection.ImportSectionEntry entry = importSection.Entries[(int)fixupIndex];
                    _fixupCells.Add(new FixupCell(_fixupCells.Count, curTableIndex, fixupIndex, entry.Signature));

                    uint delta = reader.ReadUInt();

                    // Delta of 0 means end of entries in this table
                    if (delta == 0)
                    {
                        break;
                    }

                    fixupIndex += delta;
                }

                uint tableIndex = reader.ReadUInt();

                if (tableIndex == 0)
                {
                    break;
                }

                curTableIndex = curTableIndex + tableIndex;
            } // Done with all entries in this table
        }
Пример #5
0
        private FixupCell[] DecodeFixupCells(int offset)
        {
            List <FixupCell> cells  = new List <FixupCell>();
            NibbleReader     reader = new NibbleReader(Image, offset);

            // The following algorithm has been loosely ported from CoreCLR,
            // src\vm\ceeload.inl, BOOL Module::FixupDelayListAux
            uint curTableIndex = reader.ReadUInt();

            while (true)
            {
                uint fixupIndex = reader.ReadUInt(); // Accumulate the real rva from the delta encoded rva

                while (true)
                {
                    R2RImportSection importSection            = ImportSections[(int)curTableIndex];
                    R2RImportSection.ImportSectionEntry entry = importSection.Entries[(int)fixupIndex];
                    cells.Add(new FixupCell(cells.Count, curTableIndex, fixupIndex, entry.Signature));

                    uint delta = reader.ReadUInt();

                    // Delta of 0 means end of entries in this table
                    if (delta == 0)
                    {
                        break;
                    }

                    fixupIndex += delta;
                }

                uint tableIndex = reader.ReadUInt();

                if (tableIndex == 0)
                {
                    break;
                }

                curTableIndex = curTableIndex + tableIndex;
            } // Done with all entries in this table

            return(cells.ToArray());
        }
Пример #6
0
        private void EnsureInitialized()
        {
            if (_boundsList != null)
            {
                return;
            }
            ReadyToRunReader _readyToRunReader = _runtimeFunction.ReadyToRunReader;
            int offset = _offset;

            _boundsList    = new List <DebugInfoBoundsEntry>();
            _variablesList = new List <NativeVarInfo>();
            Machine machine = _readyToRunReader.Machine;

            byte[] image = _readyToRunReader.Image;
            _machine = machine;

            // Get the id of the runtime function from the NativeArray
            uint lookback        = 0;
            uint debugInfoOffset = NativeReader.DecodeUnsigned(image, (uint)offset, ref lookback);

            if (lookback != 0)
            {
                System.Diagnostics.Debug.Assert(0 < lookback && lookback < offset);
                debugInfoOffset = (uint)offset - lookback;
            }

            NibbleReader reader             = new NibbleReader(image, (int)debugInfoOffset);
            uint         boundsByteCount    = reader.ReadUInt();
            uint         variablesByteCount = reader.ReadUInt();
            int          boundsOffset       = reader.GetNextByteOffset();
            int          variablesOffset    = (int)(boundsOffset + boundsByteCount);

            if (boundsByteCount > 0)
            {
                ParseBounds(image, boundsOffset);
            }

            if (variablesByteCount > 0)
            {
                ParseNativeVarInfo(image, variablesOffset);
            }
        }
Пример #7
0
        private void ParseBounds(byte[] image, int offset)
        {
            // Bounds info contains (Native Offset, IL Offset, flags)
            // - Sorted by native offset (so use a delta encoding for that).
            // - IL offsets aren't sorted, but they should be close to each other (so a signed delta encoding)
            //   They may also include a sentinel value from MappingTypes.
            // - flags is 3 independent bits.
            NibbleReader reader           = new NibbleReader(image, offset);
            uint         boundsEntryCount = reader.ReadUInt();

            Debug.Assert(boundsEntryCount > 0);

            uint previousNativeOffset = 0;

            for (int i = 0; i < boundsEntryCount; ++i)
            {
                var entry = new DebugInfoBoundsEntry();
                previousNativeOffset += reader.ReadUInt();
                entry.NativeOffset    = previousNativeOffset;
                entry.ILOffset        = reader.ReadUInt() + (uint)DebugInfoBoundsType.MaxMappingValue;
                entry.SourceTypes     = (SourceTypes)reader.ReadUInt();
                _boundsList.Add(entry);
            }
        }
Пример #8
0
        private void ParseNativeVarInfo(byte[] image, int offset)
        {
            // Each Varinfo has a:
            // - native start +End offset. We can use a delta for the end offset.
            // - Il variable number. These are usually small.
            // - VarLoc information. This is a tagged variant.
            // The entries aren't sorted in any particular order.
            NibbleReader reader         = new NibbleReader(image, offset);
            uint         nativeVarCount = reader.ReadUInt();

            for (int i = 0; i < nativeVarCount; ++i)
            {
                var entry = new NativeVarInfo();
                entry.StartOffset    = reader.ReadUInt();
                entry.EndOffset      = entry.StartOffset + reader.ReadUInt();
                entry.VariableNumber = (uint)(reader.ReadUInt() + (int)ImplicitILArguments.Max);
                entry.Variable       = new Variable();
                // TODO: This is probably incomplete
                // This does not handle any implicit arguments or var args
                if (entry.VariableNumber < this._runtimeFunction.Method.Signature.ParameterTypes.Length)
                {
                    entry.Variable.Type  = VariableType.Parameter;
                    entry.Variable.Index = (int)entry.VariableNumber;
                }
                else
                {
                    entry.Variable.Type  = VariableType.Local;
                    entry.Variable.Index = (int)entry.VariableNumber - this._runtimeFunction.Method.Signature.ParameterTypes.Length;
                }

                var varLoc = new VarLoc();
                varLoc.VarLocType = (VarLocType)reader.ReadUInt();
                switch (varLoc.VarLocType)
                {
                case VarLocType.VLT_REG:
                case VarLocType.VLT_REG_FP:
                case VarLocType.VLT_REG_BYREF:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    break;

                case VarLocType.VLT_STK:
                case VarLocType.VLT_STK_BYREF:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    varLoc.Data2 = ReadEncodedStackOffset(reader);
                    break;

                case VarLocType.VLT_REG_REG:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    varLoc.Data2 = (int)reader.ReadUInt();
                    break;

                case VarLocType.VLT_REG_STK:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    varLoc.Data2 = (int)reader.ReadUInt();
                    varLoc.Data3 = ReadEncodedStackOffset(reader);
                    break;

                case VarLocType.VLT_STK_REG:
                    varLoc.Data1 = ReadEncodedStackOffset(reader);
                    varLoc.Data2 = (int)reader.ReadUInt();
                    varLoc.Data3 = (int)reader.ReadUInt();
                    break;

                case VarLocType.VLT_STK2:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    varLoc.Data2 = ReadEncodedStackOffset(reader);
                    break;

                case VarLocType.VLT_FPSTK:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    break;

                case VarLocType.VLT_FIXED_VA:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    break;

                default:
                    throw new BadImageFormatException("Unexpected var loc type");
                }

                entry.VariableLocation = varLoc;
                _variablesList.Add(entry);
            }
        }
Пример #9
0
        private void ParseNativeVarInfo(byte[] image, int offset)
        {
            // Each Varinfo has a:
            // - native start +End offset. We can use a delta for the end offset.
            // - Il variable number. These are usually small.
            // - VarLoc information. This is a tagged variant.
            // The entries aren't sorted in any particular order.
            NibbleReader reader         = new NibbleReader(image, offset);
            uint         nativeVarCount = reader.ReadUInt();

            for (int i = 0; i < nativeVarCount; ++i)
            {
                var entry = new NativeVarInfo();
                entry.StartOffset    = reader.ReadUInt();
                entry.EndOffset      = entry.StartOffset + reader.ReadUInt();
                entry.VariableNumber = (uint)(reader.ReadUInt() + (int)ImplicitILArguments.Max);

                var varLoc = new VarLoc();
                varLoc.VarLocType = (VarLocType)reader.ReadUInt();
                switch (varLoc.VarLocType)
                {
                case VarLocType.VLT_REG:
                case VarLocType.VLT_REG_FP:
                case VarLocType.VLT_REG_BYREF:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    break;

                case VarLocType.VLT_STK:
                case VarLocType.VLT_STK_BYREF:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    varLoc.Data2 = ReadEncodedStackOffset(reader);
                    break;

                case VarLocType.VLT_REG_REG:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    varLoc.Data2 = (int)reader.ReadUInt();
                    break;

                case VarLocType.VLT_REG_STK:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    varLoc.Data2 = (int)reader.ReadUInt();
                    varLoc.Data3 = ReadEncodedStackOffset(reader);
                    break;

                case VarLocType.VLT_STK_REG:
                    varLoc.Data1 = ReadEncodedStackOffset(reader);
                    varLoc.Data2 = (int)reader.ReadUInt();
                    varLoc.Data3 = (int)reader.ReadUInt();
                    break;

                case VarLocType.VLT_STK2:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    varLoc.Data2 = ReadEncodedStackOffset(reader);
                    break;

                case VarLocType.VLT_FPSTK:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    break;

                case VarLocType.VLT_FIXED_VA:
                    varLoc.Data1 = (int)reader.ReadUInt();
                    break;

                default:
                    throw new BadImageFormatException("Unexpected var loc type");
                }

                entry.VariableLocation = varLoc;
                _variablesList.Add(entry);
            }
        }