예제 #1
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="kind">Custom debug info kind</param>
 /// <param name="data">Raw custom debug info data</param>
 public PdbUnknownCustomDebugInfo(PdbCustomDebugInfoKind kind, byte[] data)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     this.kind = kind;
     this.data = data;
 }
예제 #2
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="guid">Custom debug info guid</param>
 /// <param name="data">Raw custom debug info data</param>
 public PdbUnknownCustomDebugInfo(Guid guid, byte[] data)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     this.kind = PdbCustomDebugInfoKind.Unknown;
     this.data = data;
     this.guid = guid;
 }
예제 #3
0
        PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong recPosEnd)
        {
            IMethodDefOrRef method;

            byte[] data;
            Local  local;
            int    count;
            int    localIndex;

            switch (recKind)
            {
            case PdbCustomDebugInfoKind.UsingGroups:
                count = reader.ReadUInt16();
                if (count < 0)
                {
                    return(null);
                }
                var usingCountRec = new PdbUsingGroupsCustomDebugInfo(count);
                for (int i = 0; i < count; i++)
                {
                    usingCountRec.UsingCounts.Add(reader.ReadUInt16());
                }
                return(usingCountRec);

            case PdbCustomDebugInfoKind.ForwardMethodInfo:
                method = module.ResolveToken(reader.ReadUInt32(), gpContext) as IMethodDefOrRef;
                if (method == null)
                {
                    return(null);
                }
                return(new PdbForwardMethodInfoCustomDebugInfo(method));

            case PdbCustomDebugInfoKind.ForwardModuleInfo:
                method = module.ResolveToken(reader.ReadUInt32(), gpContext) as IMethodDefOrRef;
                if (method == null)
                {
                    return(null);
                }
                return(new PdbForwardModuleInfoCustomDebugInfo(method));

            case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes:
                if (bodyOpt == null)
                {
                    return(null);
                }
                count = reader.ReadInt32();
                if (count < 0)
                {
                    return(null);
                }
                var smScope = new PdbStateMachineHoistedLocalScopesCustomDebugInfo(count);
                for (int i = 0; i < count; i++)
                {
                    uint startOffset = reader.ReadUInt32();
                    uint endOffset   = reader.ReadUInt32();
                    if (startOffset > endOffset)
                    {
                        return(null);
                    }
                    // Try to detect synthesized locals, whose start==end==0. The problem is that endOffset
                    // read from the PDB is inclusive (add 1 to get 'end'), so a synthesized local and a
                    // local at [0, 1) will be encoded the same {0, 0}.
                    if (endOffset == 0)
                    {
                        smScope.Scopes.Add(new StateMachineHoistedLocalScope());
                    }
                    else
                    {
                        var start = GetInstruction(startOffset);
                        var end   = GetInstruction(endOffset + 1);
                        if (start == null)
                        {
                            return(null);
                        }
                        smScope.Scopes.Add(new StateMachineHoistedLocalScope(start, end));
                    }
                }
                return(smScope);

            case PdbCustomDebugInfoKind.StateMachineTypeName:
                var name = ReadUnicodeZ(recPosEnd, needZeroChar: true);
                if (name == null)
                {
                    return(null);
                }
                var type = GetNestedType(name);
                if (type == null)
                {
                    return(null);
                }
                return(new PdbStateMachineTypeNameCustomDebugInfo(type));

            case PdbCustomDebugInfoKind.DynamicLocals:
                if (bodyOpt == null)
                {
                    return(null);
                }
                count = reader.ReadInt32();
                const int dynLocalRecSize = 64 + 4 + 4 + 2 * 64;
                if (reader.Position + (ulong)(uint)count * dynLocalRecSize > recPosEnd)
                {
                    return(null);
                }
                var dynLocListRec = new PdbDynamicLocalsCustomDebugInfo(count);
                for (int i = 0; i < count; i++)
                {
                    reader.Position += 64;
                    int flagsCount = reader.ReadInt32();
                    if ((uint)flagsCount > 64)
                    {
                        return(null);
                    }
                    var dynLocRec = new PdbDynamicLocal(flagsCount);
                    var afterPos  = reader.Position;

                    reader.Position -= 64 + 4;
                    for (int j = 0; j < flagsCount; j++)
                    {
                        dynLocRec.Flags.Add(reader.ReadByte());
                    }
                    reader.Position = afterPos;

                    localIndex = reader.ReadInt32();
                    // 'const' locals have index -1 but they're encoded as 0 by Roslyn
                    if (localIndex != 0 && (uint)localIndex >= (uint)bodyOpt.Variables.Count)
                    {
                        return(null);
                    }

                    var nameEndPos = reader.Position + 2 * 64;
                    name            = ReadUnicodeZ(nameEndPos, needZeroChar: false);
                    reader.Position = nameEndPos;

                    local = localIndex < bodyOpt.Variables.Count ? bodyOpt.Variables[localIndex] : null;
                    // Roslyn writes 0 to localIndex if it's a 'const' local, try to undo that now
                    if (localIndex == 0 && local != null && local.Name != name)
                    {
                        local = null;
                    }
                    if (local != null && local.Name == name)
                    {
                        name = null;
                    }
                    dynLocRec.Name  = name;
                    dynLocRec.Local = local;
                    dynLocListRec.Locals.Add(dynLocRec);
                }
                return(dynLocListRec);

            case PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap:
                data = reader.ReadBytes((int)(recPosEnd - reader.Position));
                return(new PdbEditAndContinueLocalSlotMapCustomDebugInfo(data));

            case PdbCustomDebugInfoKind.EditAndContinueLambdaMap:
                data = reader.ReadBytes((int)(recPosEnd - reader.Position));
                return(new PdbEditAndContinueLambdaMapCustomDebugInfo(data));

            case PdbCustomDebugInfoKind.TupleElementNames:
                if (bodyOpt == null)
                {
                    return(null);
                }
                count = reader.ReadInt32();
                if (count < 0)
                {
                    return(null);
                }
                var tupleListRec = new PdbTupleElementNamesCustomDebugInfo(count);
                for (int i = 0; i < count; i++)
                {
                    int nameCount = reader.ReadInt32();
                    if ((uint)nameCount >= 10000)
                    {
                        return(null);
                    }
                    var tupleInfo = new PdbTupleElementNames(nameCount);

                    for (int j = 0; j < nameCount; j++)
                    {
                        var s = ReadUTF8Z(recPosEnd);
                        if (s == null)
                        {
                            return(null);
                        }
                        tupleInfo.TupleElementNames.Add(s);
                    }

                    localIndex = reader.ReadInt32();
                    uint scopeStart = reader.ReadUInt32();
                    uint scopeEnd   = reader.ReadUInt32();
                    name = ReadUTF8Z(recPosEnd);
                    if (name == null)
                    {
                        return(null);
                    }
                    Debug.Assert(localIndex >= -1);
                    // -1 = 'const' local. Only 'const' locals have a scope
                    Debug.Assert((localIndex == -1) ^ (scopeStart == 0 && scopeEnd == 0));

                    if (localIndex == -1)
                    {
                        local = null;
                        tupleInfo.ScopeStart = GetInstruction(scopeStart);
                        tupleInfo.ScopeEnd   = GetInstruction(scopeEnd);
                        if (tupleInfo.ScopeStart == null)
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        if ((uint)localIndex >= (uint)bodyOpt.Variables.Count)
                        {
                            return(null);
                        }
                        local = bodyOpt.Variables[localIndex];
                    }

                    if (local != null && local.Name == name)
                    {
                        name = null;
                    }
                    tupleInfo.Local = local;
                    tupleInfo.Name  = name;

                    tupleListRec.Names.Add(tupleInfo);
                }
                return(tupleListRec);

            default:
                Debug.Fail("Unknown custom debug info kind: 0x" + ((int)recKind).ToString("X"));
                data = reader.ReadBytes((int)(recPosEnd - reader.Position));
                return(new PdbUnknownCustomDebugInfo(recKind, data));
            }
        }
예제 #4
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="guid">Custom debug info guid</param>
 /// <param name="data">Raw custom debug info data</param>
 public PdbUnknownCustomDebugInfo(Guid guid, byte[] data)
 {
     kind      = PdbCustomDebugInfoKind.Unknown;
     this.data = data ?? throw new ArgumentNullException(nameof(data));
     this.guid = guid;
 }
예제 #5
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="kind">Custom debug info kind</param>
 /// <param name="data">Raw custom debug info data</param>
 public PdbUnknownCustomDebugInfo(PdbCustomDebugInfoKind kind, byte[] data)
 {
     this.kind = kind;
     this.data = data ?? throw new ArgumentNullException(nameof(data));
     guid      = Guid.Empty;
 }