PdbCustomDebugInfo ReadStateMachineHoistedLocalScopes()
        {
            if (bodyOpt == null)
            {
                return(null);
            }
            int count   = (int)(reader.Length / 8);
            var smScope = new PdbStateMachineHoistedLocalScopesCustomDebugInfo(count);

            for (int i = 0; i < count; i++)
            {
                uint startOffset = reader.ReadUInt32();
                uint length      = reader.ReadUInt32();
                if (startOffset == 0 && length == 0)
                {
                    smScope.Scopes.Add(new StateMachineHoistedLocalScope());
                }
                else
                {
                    var start = GetInstruction(startOffset);
                    var end   = GetInstruction(startOffset + length);
                    Debug.Assert(start != null);
                    if (start == null)
                    {
                        return(null);
                    }
                    smScope.Scopes.Add(new StateMachineHoistedLocalScope(start, end));
                }
            }
            return(smScope);
        }
Esempio n. 2
0
 void WriteStateMachineHoistedLocalScopes(PdbStateMachineHoistedLocalScopesCustomDebugInfo cdi)
 {
     if (!methodContext.HasBody)
     {
         helper.Error("Method has no body, can't write custom debug info: " + cdi.Kind);
         return;
     }
     foreach (var scope in cdi.Scopes)
     {
         uint startOffset, endOffset;
         if (scope.IsSynthesizedLocal)
         {
             startOffset = 0;
             endOffset   = 0;
         }
         else
         {
             var startInstr = scope.Start;
             if (startInstr == null)
             {
                 helper.Error("Instruction is null");
                 return;
             }
             startOffset = methodContext.GetOffset(startInstr);
             endOffset   = methodContext.GetOffset(scope.End);
         }
         if (startOffset > endOffset)
         {
             helper.Error("End instruction is before start instruction");
             return;
         }
         writer.Write(startOffset);
         writer.Write(endOffset - startOffset);
     }
 }
Esempio n. 3
0
        protected override PdbCustomDebugInfo CloneOther(PdbCustomDebugInfo source)
        {
            switch (source)
            {
            case PdbAsyncMethodCustomDebugInfo i:
                var n = new PdbAsyncMethodCustomDebugInfo(i.StepInfos.Count)
                {
                    CatchHandlerInstruction = GetInstruction(i.CatchHandlerInstruction),
                    KickoffMethod           = Importer.Import(i.KickoffMethod).ResolveMethodDefThrow()
                };
                for (var j = 0; j < i.StepInfos.Count; j++)
                {
                    n.StepInfos.Add(new PdbAsyncStepInfo(
                                        GetInstruction(i.StepInfos[j].YieldInstruction),
                                        Importer.Import(i.StepInfos[j].BreakpointMethod).ResolveMethodDefThrow(),
                                        GetInstruction(i.StepInfos[j].BreakpointInstruction)
                                        ));
                }
                return(n);

            case PdbStateMachineHoistedLocalScopesCustomDebugInfo i:
                var nls = new PdbStateMachineHoistedLocalScopesCustomDebugInfo(i.Scopes.Count);
                foreach (var si in nls.Scopes)
                {
                    nls.Scopes.Add(new StateMachineHoistedLocalScope(
                                       GetInstruction(si.Start),
                                       GetInstruction(si.End)));
                }
                return(nls);

            case PdbIteratorMethodCustomDebugInfo i:
                var im = new PdbIteratorMethodCustomDebugInfo
                {
                    KickoffMethod = Importer.Import(i.KickoffMethod).ResolveMethodDefThrow()
                };
                return(im);

            case PdbDynamicLocalsCustomDebugInfo i:
                var ndl = new PdbDynamicLocalsCustomDebugInfo(i.Locals.Count);
                foreach (var si in ndl.Locals)
                {
                    ndl.Locals.Add(Clone(si));
                }
                return(ndl);

            case PdbEditAndContinueLocalSlotMapCustomDebugInfo i2:
            case PdbEditAndContinueLambdaMapCustomDebugInfo i3:
                return(source);
            }

            return(null);
        }
        void WriteStateMachineHoistedLocalScopes(PdbStateMachineHoistedLocalScopesCustomDebugInfo cdi)
        {
            if (!methodContext.HasBody)
            {
                helper.Error2("Method has no body, can't write custom debug info: {0}.", cdi.Kind);
                return;
            }
            var cdiScopes = cdi.Scopes;
            int count     = cdiScopes.Count;

            for (int i = 0; i < count; i++)
            {
                var  scope = cdiScopes[i];
                uint startOffset, endOffset;
                if (scope.IsSynthesizedLocal)
                {
                    startOffset = 0;
                    endOffset   = 0;
                }
                else
                {
                    var startInstr = scope.Start;
                    if (startInstr is null)
                    {
                        helper.Error("Instruction is null");
                        return;
                    }
                    startOffset = methodContext.GetOffset(startInstr);
                    endOffset   = methodContext.GetOffset(scope.End);
                }
                if (startOffset > endOffset)
                {
                    helper.Error("End instruction is before start instruction");
                    return;
                }
                writer.WriteUInt32(startOffset);
                writer.WriteUInt32(endOffset - startOffset);
            }
        }
Esempio n. 5
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));
            }
        }