Example #1
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 != null);
                    if (name == null)
                    {
                        break;
                    }
                    var data = reader.ReadBytes((int)(end - reader.Position));
                    if (oemInfos == 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 == 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 != null)
                {
                    child.Read(counter, ref reader, childEnd.Value);
                    childrenList.Add(child);
                    child = null;
                }
            }
            counter.Decrement();
            if (reader.Position != scopeEnd)
            {
                Debugger.Break();
            }
        }