Exemplo n.º 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 is null)
            {
                while (found > 0)
                {
                    var prevFunc = funcs[found - 1];
                    if (prevFunc is not null || prevFunc.Address != address)
                    {
                        break;
                    }
                    found--;
                }
            }
            else
            {
                while (found < funcs.Length - 1 && funcs[found] is not null)
                {
                    var nextFunc = funcs[found + 1];
                    if (nextFunc.Address != address)
                    {
                        break;
                    }
                    found++;
                }
            }
            var func = funcs[found];

            if (func.Lines is not 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);
                }
            }
        }
Exemplo n.º 2
0
        public void Read(RecursionCounter counter, ref DataReader reader, uint scopeEnd)
        {
            if (!counter.Increment())
            {
                throw new PdbException("Scopes too deep");
            }

            while (reader.Position < scopeEnd)
            {
                var size  = reader.ReadUInt16();
                var begin = reader.Position;
                var end   = begin + size;

                var      type     = (SymbolType)reader.ReadUInt16();
                DbiScope child    = null;
                uint?    childEnd = null;
                string   name;
                switch (type)
                {
                case SymbolType.S_BLOCK32: {
                    reader.Position += 4;
                    childEnd         = reader.ReadUInt32();
                    var len  = reader.ReadUInt32();
                    var addr = PdbAddress.ReadAddress(ref reader);
                    name  = PdbReader.ReadCString(ref reader);
                    child = new DbiScope(method, this, name, addr.Offset, len);
                    break;
                }

                case SymbolType.S_UNAMESPACE:
                    namespacesList.Add(new DbiNamespace(PdbReader.ReadCString(ref reader)));
                    break;

                case SymbolType.S_MANSLOT: {
                    var variable = new DbiVariable();
                    if (variable.Read(ref reader))
                    {
                        localsList.Add(variable);
                    }
                    break;
                }

                case SymbolType.S_OEM:
                    if ((ulong)reader.Position + 20 > end)
                    {
                        break;
                    }
                    if (!ReadAndCompareBytes(ref reader, end, dotNetOemGuid))
                    {
                        Debug.Fail("Unknown OEM record GUID, not .NET GUID");
                        break;
                    }
                    reader.Position += 4;                            // typeIndex or 0
                    name             = ReadUnicodeString(ref reader, end);
                    Debug.Assert(name is not null);
                    if (name is null)
                    {
                        break;
                    }
                    var data = reader.ReadBytes((int)(end - reader.Position));
                    if (oemInfos is null)
                    {
                        oemInfos = new List <OemInfo>(1);
                    }
                    oemInfos.Add(new OemInfo(name, data));
                    break;

                case SymbolType.S_MANCONSTANT:
                    uint   signatureToken = reader.ReadUInt32();
                    object value;
                    if (!NumericReader.TryReadNumeric(ref reader, end, out value))
                    {
                        break;
                    }
                    name = PdbReader.ReadCString(ref reader);
                    if (constants is null)
                    {
                        constants = new List <ConstantInfo>();
                    }
                    constants.Add(new ConstantInfo(name, signatureToken, value));
                    break;

                case SymbolType.S_END:
                    break;

                default:
                    break;
                }

                reader.Position = end;
                if (child is not null)
                {
                    child.Read(counter, ref reader, childEnd.Value);
                    childrenList.Add(child);
                    child = null;
                }
            }
            counter.Decrement();
            if (reader.Position != scopeEnd)
            {
                Debugger.Break();
            }
        }