예제 #1
0
        void ReadLines(DbiFunction[] funcs, Dictionary <uint, DbiDocument> documents, ref DataReader reader, uint end)
        {
            var address = PdbAddress.ReadAddress(ref reader);

            int first = 0;
            int last  = funcs.Length - 1;
            int found = -1;

            while (first <= last)
            {
                var index = first + ((last - first) >> 1);
                var addr  = funcs[index].Address;
                if (addr < address)
                {
                    first = index + 1;
                }
                else if (addr > address)
                {
                    last = index - 1;
                }
                else
                {
                    found = index;
                    break;
                }
            }
            if (found == -1)
            {
                return;
            }

            var flags = reader.ReadUInt16();

            reader.Position += 4;

            if (funcs[found].Lines == null)
            {
                while (found > 0)
                {
                    var prevFunc = funcs[found - 1];
                    if (prevFunc != null || prevFunc.Address != address)
                    {
                        break;
                    }
                    found--;
                }
            }
            else
            {
                while (found < funcs.Length - 1 && funcs[found] != null)
                {
                    var nextFunc = funcs[found + 1];
                    if (nextFunc.Address != address)
                    {
                        break;
                    }
                    found++;
                }
            }
            var func = funcs[found];

            if (func.Lines != null)
            {
                return;
            }
            func.Lines = new List <SymbolSequencePoint>();

            while (reader.Position < end)
            {
                var document = documents[reader.ReadUInt32()];
                var count    = reader.ReadUInt32();
                reader.Position += 4;

                const int LINE_ENTRY_SIZE = 8;
                const int COL_ENTRY_SIZE  = 4;
                var       lineTablePos    = reader.Position;
                var       colTablePos     = reader.Position + count * LINE_ENTRY_SIZE;

                for (uint i = 0; i < count; i++)
                {
                    reader.Position = lineTablePos + i * LINE_ENTRY_SIZE;

                    var line = new SymbolSequencePoint {
                        Document = document
                    };
                    line.Offset = reader.ReadInt32();
                    var lineFlags = reader.ReadUInt32();

                    line.Line    = (int)(lineFlags & 0x00ffffff);
                    line.EndLine = line.Line + (int)((lineFlags >> 24) & 0x7F);
                    if ((flags & 1) != 0)
                    {
                        reader.Position = colTablePos + i * COL_ENTRY_SIZE;
                        line.Column     = reader.ReadUInt16();
                        line.EndColumn  = reader.ReadUInt16();
                    }

                    func.Lines.Add(line);
                }
            }
        }
예제 #2
0
        SymbolSequencePoint[] ReadSequencePoints(uint methodRid)
        {
            if (!pdbMetadata.TablesStream.MethodDebugInformationTable.IsValidRID(methodRid))
            {
                return(null);
            }
            if (!pdbMetadata.TablesStream.TryReadMethodDebugInformationRow(methodRid, out var row))
            {
                return(null);
            }
            if (row.SequencePoints == 0)
            {
                return(null);
            }
            uint documentRid = row.Document;

            if (!pdbMetadata.BlobStream.TryCreateReader(row.SequencePoints, out var seqPointsReader))
            {
                return(null);
            }
            var seqPointsBuilder = ListCache <SymbolSequencePoint> .AllocList();

            uint localSig = seqPointsReader.ReadCompressedUInt32();

            if (documentRid == 0)
            {
                documentRid = seqPointsReader.ReadCompressedUInt32();
            }

            TryGetSymbolDocument(documentRid, out var document);

            uint ilOffset = uint.MaxValue;
            int  line = -1, column = 0;
            bool canReadDocumentRecord = false;

            while (seqPointsReader.Position < seqPointsReader.Length)
            {
                uint data = seqPointsReader.ReadCompressedUInt32();
                if (data == 0 && canReadDocumentRecord)
                {
                    // document-record

                    documentRid = seqPointsReader.ReadCompressedUInt32();
                    TryGetSymbolDocument(documentRid, out document);
                }
                else
                {
                    // SequencePointRecord

                    Debug.Assert(document is not null);
                    if (document is null)
                    {
                        return(null);
                    }

                    var symSeqPoint = new SymbolSequencePoint {
                        Document = document,
                    };

                    if (ilOffset == uint.MaxValue)
                    {
                        ilOffset = data;
                    }
                    else
                    {
                        Debug.Assert(data != 0);
                        if (data == 0)
                        {
                            return(null);
                        }
                        ilOffset += data;
                    }
                    symSeqPoint.Offset = (int)ilOffset;

                    uint dlines   = seqPointsReader.ReadCompressedUInt32();
                    int  dcolumns = dlines == 0 ? (int)seqPointsReader.ReadCompressedUInt32() : seqPointsReader.ReadCompressedInt32();

                    if (dlines == 0 && dcolumns == 0)
                    {
                        // hidden-sequence-point-record

                        symSeqPoint.Line      = SequencePointConstants.HIDDEN_LINE;
                        symSeqPoint.EndLine   = SequencePointConstants.HIDDEN_LINE;
                        symSeqPoint.Column    = SequencePointConstants.HIDDEN_COLUMN;
                        symSeqPoint.EndColumn = SequencePointConstants.HIDDEN_COLUMN;
                    }
                    else
                    {
                        // sequence-point-record

                        if (line < 0)
                        {
                            line   = (int)seqPointsReader.ReadCompressedUInt32();
                            column = (int)seqPointsReader.ReadCompressedUInt32();
                        }
                        else
                        {
                            line   += seqPointsReader.ReadCompressedInt32();
                            column += seqPointsReader.ReadCompressedInt32();
                        }

                        symSeqPoint.Line      = line;
                        symSeqPoint.EndLine   = line + (int)dlines;
                        symSeqPoint.Column    = column;
                        symSeqPoint.EndColumn = column + dcolumns;
                    }

                    seqPointsBuilder.Add(symSeqPoint);
                }

                canReadDocumentRecord = true;
            }
            Debug.Assert(seqPointsReader.Position == seqPointsReader.Length);

            return(ListCache <SymbolSequencePoint> .FreeAndToArray(ref seqPointsBuilder));
        }