Beispiel #1
0
        public MethodDebugInformation Read(MethodDefinition method)
        {
            var method_token = method.MetadataToken;

            PdbFunction function;

            if (!functions.TryGetValue(method_token.ToUInt32(), out function))
            {
                return(null);
            }

            var symbol = new MethodDebugInformation(method);

            ReadSequencePoints(function, symbol);

            symbol.scope = !function.scopes.IsNullOrEmpty()
                                ? ReadScopeAndLocals(function.scopes [0], symbol)
                                : new ScopeDebugInformation {
                Start = new InstructionOffset(0), End = new InstructionOffset((int)function.length)
            };

            if (function.tokenOfMethodWhoseUsingInfoAppliesToThisMethod != method.MetadataToken.ToUInt32() && function.tokenOfMethodWhoseUsingInfoAppliesToThisMethod != 0)
            {
                symbol.scope.import = GetImport(function.tokenOfMethodWhoseUsingInfoAppliesToThisMethod, method.Module);
            }

            if (function.scopes.Length > 1)
            {
                for (int i = 1; i < function.scopes.Length; i++)
                {
                    var s = ReadScopeAndLocals(function.scopes [i], symbol);
                    if (!AddScope(symbol.scope.Scopes, s))
                    {
                        symbol.scope.Scopes.Add(s);
                    }
                }
            }

            if (function.iteratorScopes != null)
            {
                var state_machine = new StateMachineScopeDebugInformation();

                foreach (var iterator_scope in function.iteratorScopes)
                {
                    state_machine.Scopes.Add(new StateMachineScope((int)iterator_scope.Offset, (int)(iterator_scope.Offset + iterator_scope.Length + 1)));
                }

                symbol.CustomDebugInformations.Add(state_machine);
            }

            if (function.synchronizationInformation != null)
            {
                var async_debug_info = new AsyncMethodBodyDebugInformation((int)function.synchronizationInformation.GeneratedCatchHandlerOffset);

                foreach (var synchronization_point in function.synchronizationInformation.synchronizationPoints)
                {
                    async_debug_info.Yields.Add(new InstructionOffset((int)synchronization_point.SynchronizeOffset));
                    async_debug_info.Resumes.Add(new InstructionOffset((int)synchronization_point.ContinuationOffset));
                    async_debug_info.ResumeMethods.Add(method);
                }

                symbol.CustomDebugInformations.Add(async_debug_info);

                symbol.StateMachineKickOffMethod = (MethodDefinition)method.Module.LookupToken((int)function.synchronizationInformation.kickoffMethodToken);
            }

            return(symbol);
        }
Beispiel #2
0
        ScopeDebugInformation ReadScopeAndLocals(PdbScope scope, MethodDebugInformation info)
        {
            var parent = new ScopeDebugInformation();

            parent.Start = new InstructionOffset((int)scope.offset);
            parent.End   = new InstructionOffset((int)(scope.offset + scope.length));

            if (!scope.slots.IsNullOrEmpty())
            {
                parent.variables = new Collection <VariableDebugInformation> (scope.slots.Length);

                foreach (PdbSlot slot in scope.slots)
                {
                    if (slot.flags == 1)                     // parameter names
                    {
                        continue;
                    }

                    var index    = (int)slot.slot;
                    var variable = new VariableDebugInformation(index, slot.name);
                    if (slot.flags == 4)
                    {
                        variable.IsDebuggerHidden = true;
                    }
                    parent.variables.Add(variable);
                }
            }

            if (!scope.constants.IsNullOrEmpty())
            {
                parent.constants = new Collection <ConstantDebugInformation> (scope.constants.Length);

                foreach (var constant in scope.constants)
                {
                    var type  = info.Method.Module.Read(constant, (c, r) => r.ReadConstantSignature(new MetadataToken(c.token)));
                    var value = constant.value;

                    // Object "null" is encoded as integer
                    if (type != null && !type.IsValueType && value is int && (int)value == 0)
                    {
                        value = null;
                    }

                    parent.constants.Add(new ConstantDebugInformation(constant.name, type, value));
                }
            }

            if (!scope.usedNamespaces.IsNullOrEmpty())
            {
                ImportDebugInformation import;
                if (imports.TryGetValue(scope, out import))
                {
                    parent.import = import;
                }
                else
                {
                    import = GetImport(scope, info.Method.Module);
                    imports.Add(scope, import);
                    parent.import = import;
                }
            }

            parent.scopes = ReadScopeAndLocals(scope.scopes, info);

            return(parent);
        }
 public void Write(MethodDebugInformation info) => throw new NotImplementedException();
Beispiel #4
0
        public static void Generate(DynamicMethodDefinition dmd, MethodBase _mb, ILGenerator il)
        {
            MethodDefinition def = dmd.Definition;
            DynamicMethod    dm  = _mb as DynamicMethod;

#if !NETSTANDARD
            MethodBuilder mb            = _mb as MethodBuilder;
            ModuleBuilder moduleBuilder = mb?.Module as ModuleBuilder;
            // moduleBuilder.Assembly sometimes avoids the .Assembly override under mysterious circumstances.
            AssemblyBuilder    assemblyBuilder     = (mb?.DeclaringType as TypeBuilder)?.Assembly as AssemblyBuilder;
            HashSet <Assembly> accessChecksIgnored = null;
            if (mb != null)
            {
                accessChecksIgnored = new HashSet <Assembly>();
            }
#endif

#if !CECIL0_9
            MethodDebugInformation defInfo = dmd.Debug ? def.DebugInformation : null;
#endif

            if (dm != null)
            {
                foreach (ParameterDefinition param in def.Parameters)
                {
                    dm.DefineParameter(param.Index + 1, (System.Reflection.ParameterAttributes)param.Attributes, param.Name);
                }
            }
#if !NETSTANDARD
            if (mb != null)
            {
                foreach (ParameterDefinition param in def.Parameters)
                {
                    mb.DefineParameter(param.Index + 1, (System.Reflection.ParameterAttributes)param.Attributes, param.Name);
                }
            }
#endif

            LocalBuilder[] locals = def.Body.Variables.Select(
                var => {
                LocalBuilder local = il.DeclareLocal(var.VariableType.ResolveReflection(), var.IsPinned);
#if !NETSTANDARD && !CECIL0_9
                if (mb != null && defInfo != null && defInfo.TryGetName(var, out string name))
                {
                    local.SetLocalSymInfo(name);
                }
#endif
                return(local);
            }
                ).ToArray();

            // Pre-pass - Set up label map.
            Dictionary <Instruction, Label> labelMap = new Dictionary <Instruction, Label>();
            foreach (Instruction instr in def.Body.Instructions)
            {
                if (instr.Operand is Instruction[] targets)
                {
                    foreach (Instruction target in targets)
                    {
                        if (!labelMap.ContainsKey(target))
                        {
                            labelMap[target] = il.DefineLabel();
                        }
                    }
                }
                else if (instr.Operand is Instruction target)
                {
                    if (!labelMap.ContainsKey(target))
                    {
                        labelMap[target] = il.DefineLabel();
                    }
                }
            }

#if !NETSTANDARD && !CECIL0_9
            Dictionary <Document, ISymbolDocumentWriter> infoDocCache = mb == null ? null : new Dictionary <Document, ISymbolDocumentWriter>();
#endif

            int      paramOffs        = def.HasThis ? 1 : 0;
            object[] emitArgs         = new object[2];
            bool     checkTryEndEarly = false;
            foreach (Instruction instr in def.Body.Instructions)
            {
                if (labelMap.TryGetValue(instr, out Label label))
                {
                    il.MarkLabel(label);
                }

#if !NETSTANDARD && !CECIL0_9
                SequencePoint instrInfo = defInfo?.GetSequencePoint(instr);
                if (mb != null && instrInfo != null)
                {
                    if (!infoDocCache.TryGetValue(instrInfo.Document, out ISymbolDocumentWriter infoDoc))
                    {
                        infoDocCache[instrInfo.Document] = infoDoc = moduleBuilder.DefineDocument(
                            instrInfo.Document.Url,
                            instrInfo.Document.LanguageGuid,
                            instrInfo.Document.LanguageVendorGuid,
                            instrInfo.Document.TypeGuid
                            );
                    }
                    il.MarkSequencePoint(infoDoc, instrInfo.StartLine, instrInfo.StartColumn, instrInfo.EndLine, instrInfo.EndColumn);
                }
#endif

                foreach (ExceptionHandler handler in def.Body.ExceptionHandlers)
                {
                    if (checkTryEndEarly && handler.HandlerEnd == instr)
                    {
                        il.EndExceptionBlock();
                    }

                    if (handler.TryStart == instr)
                    {
                        il.BeginExceptionBlock();
                    }
                    else if (handler.FilterStart == instr)
                    {
                        il.BeginExceptFilterBlock();
                    }
                    else if (handler.HandlerStart == instr)
                    {
                        switch (handler.HandlerType)
                        {
                        case ExceptionHandlerType.Filter:
                            il.BeginCatchBlock(null);
                            break;

                        case ExceptionHandlerType.Catch:
                            il.BeginCatchBlock(handler.CatchType.ResolveReflection());
                            break;

                        case ExceptionHandlerType.Finally:
                            il.BeginFinallyBlock();
                            break;

                        case ExceptionHandlerType.Fault:
                            il.BeginFaultBlock();
                            break;
                        }
                    }

                    // Avoid duplicate endfilter / endfinally
                    if (handler.HandlerStart == instr.Next)
                    {
                        switch (handler.HandlerType)
                        {
                        case ExceptionHandlerType.Filter:
                            if (instr.OpCode == Mono.Cecil.Cil.OpCodes.Endfilter)
                            {
                                goto SkipEmit;
                            }
                            break;

                        case ExceptionHandlerType.Finally:
                            if (instr.OpCode == Mono.Cecil.Cil.OpCodes.Endfinally)
                            {
                                goto SkipEmit;
                            }
                            break;
                        }
                    }
                }

                if (instr.OpCode.OperandType == Mono.Cecil.Cil.OperandType.InlineNone)
                {
                    il.Emit(_ReflOpCodes[instr.OpCode.Value]);
                }
                else
                {
                    object operand = instr.Operand;

                    if (operand is Instruction[] targets)
                    {
                        operand = targets.Select(target => labelMap[target]).ToArray();
                        // Let's hope that the JIT treats the long forms identically to the short forms.
                        instr.OpCode = instr.OpCode.ToLongOp();
                    }
                    else if (operand is Instruction target)
                    {
                        operand = labelMap[target];
                        // Let's hope that the JIT treats the long forms identically to the short forms.
                        instr.OpCode = instr.OpCode.ToLongOp();
                    }
                    else if (operand is VariableDefinition var)
                    {
                        operand = locals[var.Index];
                    }
                    else if (operand is ParameterDefinition param)
                    {
                        operand = param.Index + paramOffs;
                    }
                    else if (operand is MemberReference mref)
                    {
                        MemberInfo member = mref.ResolveReflection();
                        operand = member;
#if !NETSTANDARD
                        if (mb != null && member != null)
                        {
                            Assembly asm = member.Module?.Assembly;
                            if (asm != null && !accessChecksIgnored.Contains(asm))
                            {
                                // while (member.DeclaringType != null)
                                //     member = member.DeclaringType;
                                assemblyBuilder.SetCustomAttribute(new CustomAttributeBuilder(DynamicMethodDefinition.c_IgnoresAccessChecksToAttribute, new object[] {
                                    asm.GetName().Name
                                }));
                                accessChecksIgnored.Add(asm);
                            }
                        }
#endif
                    }
                    else if (operand is CallSite csite)
                    {
                        if (dm != null)
                        {
                            // SignatureHelper in unmanaged contexts cannot be fully made use of for DynamicMethods.
                            _EmitCallSite(dm, il, _ReflOpCodes[instr.OpCode.Value], csite);
                            continue;
                        }
#if !NETSTANDARD
                        operand = csite.ResolveReflection(mb.Module);
#else
                        throw new NotSupportedException();
#endif
                    }

#if !NETSTANDARD
                    if (mb != null && operand is MethodBase called && called.DeclaringType == null)
                    {
                        // "Global" methods (f.e. DynamicMethods) cannot be tokenized.
                        if (instr.OpCode == Mono.Cecil.Cil.OpCodes.Call)
                        {
                            if (operand is DynamicMethod target)
                            {
                                // This should be heavily optimizable.
                                operand = _CreateMethodProxy(mb, target);
                            }
                            else
                            {
                                IntPtr ptr = called.GetLdftnPointer();
                                if (IntPtr.Size == 4)
                                {
                                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)ptr);
                                }
                                else
                                {
                                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_I8, (long)ptr);
                                }
                                il.Emit(System.Reflection.Emit.OpCodes.Conv_I);
                                instr.OpCode = Mono.Cecil.Cil.OpCodes.Calli;
                                operand      = ((MethodReference)instr.Operand).ResolveReflectionSignature(mb.Module);
                            }
                        }
                        else
                        {
                            throw new NotSupportedException($"Unsupported global method operand on opcode {instr.OpCode.Name}");
                        }
                    }
#endif

                    if (operand == null)
                    {
                        throw new NullReferenceException($"Unexpected null in {def} @ {instr}");
                    }

                    il.DynEmit(_ReflOpCodes[instr.OpCode.Value], operand);
                }

                if (!checkTryEndEarly)
                {
                    foreach (ExceptionHandler handler in def.Body.ExceptionHandlers)
                    {
                        if (handler.HandlerEnd == instr.Next)
                        {
                            il.EndExceptionBlock();
                        }
                    }
                }

                checkTryEndEarly = false;
                continue;

SkipEmit:
                checkTryEndEarly = true;
                continue;
            }
        }
        void DefineScope(ScopeDebugInformation scope, MethodDebugInformation info, out MetadataToken import_parent)
        {
            var start_offset = scope.Start.Offset;
            var end_offset   = scope.End.IsEndOfMethod
                                ? info.code_size
                                : scope.End.Offset;

            import_parent = new MetadataToken(0u);

            writer.OpenScope(start_offset);

            if (scope.Import != null && scope.Import.HasTargets && !import_info_to_parent.TryGetValue(info.scope.Import, out import_parent))
            {
                foreach (var target in scope.Import.Targets)
                {
                    switch (target.Kind)
                    {
                    case ImportTargetKind.ImportNamespace:
                        writer.UsingNamespace("U" + target.@namespace);
                        break;

                    case ImportTargetKind.ImportType:
                        writer.UsingNamespace("T" + TypeParser.ToParseable(target.type));
                        break;

                    case ImportTargetKind.DefineNamespaceAlias:
                        writer.UsingNamespace("A" + target.Alias + " U" + target.@namespace);
                        break;

                    case ImportTargetKind.DefineTypeAlias:
                        writer.UsingNamespace("A" + target.Alias + " T" + TypeParser.ToParseable(target.type));
                        break;
                    }
                }

                import_info_to_parent.Add(info.scope.Import, info.method.MetadataToken);
            }

            var sym_token = info.local_var_token.ToInt32();

            if (!scope.variables.IsNullOrEmpty())
            {
                for (int i = 0; i < scope.variables.Count; i++)
                {
                    var variable = scope.variables [i];
                    DefineLocalVariable(variable, sym_token, start_offset, end_offset);
                }
            }

            if (!scope.constants.IsNullOrEmpty())
            {
                for (int i = 0; i < scope.constants.Count; i++)
                {
                    var constant = scope.constants [i];
                    DefineConstant(constant);
                }
            }

            if (!scope.scopes.IsNullOrEmpty())
            {
                for (int i = 0; i < scope.scopes.Count; i++)
                {
                    MetadataToken _;
                    DefineScope(scope.scopes [i], info, out _);
                }
            }

            writer.CloseScope(end_offset);
        }
Beispiel #6
0
        public void CompileMethod(CppMethodCodeNode methodCodeNodeNeedingCode)
        {
            MethodDesc method = methodCodeNodeNeedingCode.Method;

            _compilation.Log.WriteLine("Compiling " + method.ToString());
            if (method.HasCustomAttribute("System.Runtime", "RuntimeImportAttribute"))
            {
                CompileExternMethod(methodCodeNodeNeedingCode, ((EcmaMethod)method).GetRuntimeImportName());
                return;
            }

            if (method.IsRawPInvoke())
            {
                CompileExternMethod(methodCodeNodeNeedingCode, method.GetPInvokeMethodMetadata().Name ?? method.Name);
                return;
            }

            var methodIL = _compilation.GetMethodIL(method);

            if (methodIL == null)
            {
                return;
            }

            // TODO: Remove this code once CppCodegen is able to generate code for the reflection startup path.
            //       The startup path runs before any user code is executed.
            //       For now we replace the startup path with a simple "ret". Reflection won't work, but
            //       programs not using reflection will.
            if (method.Name == ".cctor")
            {
                MetadataType owningType = method.OwningType as MetadataType;
                if (owningType != null &&
                    owningType.Name == "ReflectionExecution" && owningType.Namespace == "Internal.Reflection.Execution")
                {
                    methodIL = new Internal.IL.Stubs.ILStubMethodIL(method, new byte[] { (byte)ILOpcode.ret }, Array.Empty <LocalVariableDefinition>(), null);
                }
            }

            try
            {
                // TODO: hacky special-case
                if (method.Name == "_ecvt_s")
                {
                    throw new NotImplementedException();
                }

                var ilImporter = new ILImporter(_compilation, this, method, methodIL);

                CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext;

                MethodDebugInformation debugInfo = _compilation.GetDebugInfo(methodIL);

                if (!_compilation.Options.NoLineNumbers)
                {
                    IEnumerable <ILSequencePoint> sequencePoints = debugInfo.GetSequencePoints();
                    if (sequencePoints != null)
                    {
                        ilImporter.SetSequencePoints(sequencePoints);
                    }
                }

                IEnumerable <ILLocalVariable> localVariables = debugInfo.GetLocalVariables();
                if (localVariables != null)
                {
                    ilImporter.SetLocalVariables(localVariables);
                }

                IEnumerable <string> parameters = GetParameterNamesForMethod(method);
                if (parameters != null)
                {
                    ilImporter.SetParameterNames(parameters);
                }

                ilImporter.Compile(methodCodeNodeNeedingCode);
            }
            catch (Exception e)
            {
                _compilation.Log.WriteLine(e.Message + " (" + method + ")");

                var builder = new CppGenerationBuffer();
                builder.AppendLine();
                builder.Append(GetCppMethodDeclaration(method, true));
                builder.AppendLine();
                builder.Append("{");
                builder.Indent();
                builder.AppendLine();
                builder.Append("throw 0xC000C000;");
                builder.Exdent();
                builder.AppendLine();
                builder.Append("}");

                methodCodeNodeNeedingCode.SetCode(builder.ToString(), Array.Empty <Object>());
            }
        }
Beispiel #7
0
        // https://github.com/dotnet/corefx/blob/9802644d90aa7fe6aba6d621724a307212303d08/src/System.Diagnostics.StackTrace.Symbols/src/System/Diagnostics/StackTrace/Symbols.cs
        private static void GetSourceLineInfo(MetadataReader reader, int methodToken, int ilOffset, out string sourceFile, out int sourceLine, out int sourceColumn)
        {
            sourceFile   = null;
            sourceLine   = 0;
            sourceColumn = 0;

            if (reader != null)
            {
                Handle handle = MetadataTokens.Handle(methodToken);

                if (handle.Kind == HandleKind.MethodDefinition)
                {
                    MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
                    MethodDebugInformation       methodInfo        = reader.GetMethodDebugInformation(methodDebugHandle);

                    if (!methodInfo.SequencePointsBlob.IsNil)
                    {
                        try
                        {
                            SequencePointCollection sequencePoints = methodInfo.GetSequencePoints();

                            int sequencePointCount = 0;
                            foreach (SequencePoint sequence in sequencePoints)
                            {
                                sequencePointCount++;
                            }

                            if (sequencePointCount > 0)
                            {
                                int[]            offsets   = new int[sequencePointCount];
                                int[]            lines     = new int[sequencePointCount];
                                int[]            columns   = new int[sequencePointCount];
                                DocumentHandle[] documents = new DocumentHandle[sequencePointCount];

                                int i = 0;
                                foreach (SequencePoint sequence in sequencePoints)
                                {
                                    offsets[i]   = sequence.Offset;
                                    lines[i]     = sequence.StartLine;
                                    columns[i]   = sequence.StartColumn;
                                    documents[i] = sequence.Document;
                                    i++;
                                }

                                // Search for the correct IL offset
                                int j;
                                for (j = 0; j < sequencePointCount; j++)
                                {
                                    // look for the entry matching the one we're looking for
                                    if (offsets[j] >= ilOffset)
                                    {
                                        // if this offset is > what we're looking for, ajdust the index
                                        if (offsets[j] > ilOffset && j > 0)
                                        {
                                            j--;
                                        }
                                        break;
                                    }
                                }

                                // If we didn't find a match, default to the last sequence point
                                if (j == sequencePointCount)
                                {
                                    j--;
                                }

                                while (lines[j] == SequencePoint.HiddenLine && j > 0)
                                {
                                    j--;
                                }

                                if (lines[j] != SequencePoint.HiddenLine)
                                {
                                    sourceLine   = lines[j];
                                    sourceColumn = columns[j];
                                }
                                var doc = reader.GetDocument(documents[j]);
                                sourceFile = reader.GetString(doc.Name);
                            }
                        }
                        catch
                        {
                        }
                    }
                }
            }
        }
Beispiel #8
0
        public ILStubMethodIL(MethodDesc owningMethod, byte[] ilBytes, LocalVariableDefinition[] locals, Object[] tokens, ILExceptionRegion[] exceptionRegions = null, MethodDebugInformation debugInfo = null)
        {
            _ilBytes  = ilBytes;
            _locals   = locals;
            _tokens   = tokens;
            _method   = owningMethod;
            _maxStack = MaxStackNotSet;

            if (exceptionRegions == null)
            {
                exceptionRegions = Array.Empty <ILExceptionRegion>();
            }
            _exceptionRegions = exceptionRegions;

            if (debugInfo == null)
            {
                debugInfo = MethodDebugInformation.None;
            }
            _debugInformation = debugInfo;
        }
        internal static bool GetSequencePoints(IntPtr symbolReaderHandle, int methodToken, out IntPtr points, out int pointsCount)
        {
            Debug.Assert(symbolReaderHandle != IntPtr.Zero);
            pointsCount = 0;
            points      = IntPtr.Zero;

            Debug.Assert(symbolReaderHandle != IntPtr.Zero);

            GCHandle       gch    = GCHandle.FromIntPtr(symbolReaderHandle);
            MetadataReader reader = ((OpenedReader)gch.Target).Reader;

            try
            {
                Handle handle = MetadataTokens.Handle(methodToken);
                if (handle.Kind != HandleKind.MethodDefinition)
                {
                    return(false);
                }

                MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
                if (methodDebugHandle.IsNil)
                {
                    return(false);
                }

                MethodDebugInformation  methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle);
                SequencePointCollection sequencePoints  = methodDebugInfo.GetSequencePoints();

                var list = new List <DbgSequencePoint>();
                foreach (SequencePoint p in sequencePoints)
                {
                    list.Add(new DbgSequencePoint()
                    {
                        startLine   = p.StartLine,
                        endLine     = p.EndLine,
                        startColumn = p.StartColumn,
                        endColumn   = p.EndColumn,
                        offset      = p.Offset
                    });
                }

                if (list.Count == 0)
                {
                    return(true);
                }

                var    structSize = Marshal.SizeOf <DbgSequencePoint>();
                IntPtr allPoints  = Marshal.AllocCoTaskMem(list.Count * structSize);
                var    currentPtr = allPoints;

                foreach (var p in list)
                {
                    Marshal.StructureToPtr(p, currentPtr, false);
                    currentPtr = (IntPtr)(currentPtr.ToInt64() + structSize);
                }

                points      = allPoints;
                pointsCount = list.Count;
                return(true);
            }
            catch
            {
            }
            return(false);
        }
Beispiel #10
0
        internal static bool GetStepRangesFromIP(IntPtr symbolReaderHandle, int ip, int methodToken, out uint ilStartOffset, out uint ilEndOffset)
        {
            Debug.Assert(symbolReaderHandle != IntPtr.Zero);
            ilStartOffset = 0;
            ilEndOffset   = 0;

            Debug.Assert(symbolReaderHandle != IntPtr.Zero);

            GCHandle       gch    = GCHandle.FromIntPtr(symbolReaderHandle);
            MetadataReader reader = ((OpenedReader)gch.Target).Reader;

            try
            {
                Handle handle = MetadataTokens.Handle(methodToken);
                if (handle.Kind != HandleKind.MethodDefinition)
                {
                    return(false);
                }

                MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
                if (methodDebugHandle.IsNil)
                {
                    return(false);
                }

                MethodDebugInformation  methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle);
                SequencePointCollection sequencePoints  = methodDebugInfo.GetSequencePoints();

                var list = new List <SequencePoint>();
                foreach (SequencePoint p in sequencePoints)
                {
                    list.Add(p);
                }

                var pointsArray = list.ToArray();

                for (int i = 1; i < pointsArray.Length; i++)
                {
                    SequencePoint p = pointsArray[i];

                    if (p.Offset > ip && p.StartLine != 0 && p.StartLine != SequencePoint.HiddenLine)
                    {
                        ilStartOffset = (uint)pointsArray[0].Offset;
                        for (int j = i - 1; j > 0; j--)
                        {
                            if (pointsArray[j].Offset <= ip)
                            {
                                ilStartOffset = (uint)pointsArray[j].Offset;
                                break;
                            }
                        }
                        ilEndOffset = (uint)p.Offset;
                        return(true);
                    }
                }

                // let's handle correctly last step range from last sequence point till
                // end of the method.
                if (pointsArray.Length > 0)
                {
                    ilStartOffset = (uint)pointsArray[0].Offset;
                    for (int j = pointsArray.Length - 1; j > 0; j--)
                    {
                        if (pointsArray[j].Offset <= ip)
                        {
                            ilStartOffset = (uint)pointsArray[j].Offset;
                            break;
                        }
                    }
                    ilEndOffset = ilStartOffset; // Should set this to IL code size in calling code
                    return(true);
                }
            }
            catch
            {
            }
            return(false);
        }
Beispiel #11
0
        /// <summary>
        /// Returns source line number and source file name for given IL offset and method token.
        /// </summary>
        /// <param name="symbolReaderHandle">symbol reader handle returned by LoadSymbolsForModule</param>
        /// <param name="methodToken">method token</param>
        /// <param name="ilOffset">IL offset</param>
        /// <param name="sequencePoint">sequence point return</param>
        /// <returns> true if information is available</returns>
        private static bool GetSequencePointByILOffset(IntPtr symbolReaderHandle, int methodToken, long ilOffset, out DbgSequencePoint sequencePoint)
        {
            Debug.Assert(symbolReaderHandle != IntPtr.Zero);
            sequencePoint.document    = IntPtr.Zero;
            sequencePoint.startLine   = 0;
            sequencePoint.startColumn = 0;
            sequencePoint.endLine     = 0;
            sequencePoint.endColumn   = 0;
            sequencePoint.offset      = 0;

            try
            {
                GCHandle       gch    = GCHandle.FromIntPtr(symbolReaderHandle);
                MetadataReader reader = ((OpenedReader)gch.Target).Reader;

                Handle handle = MetadataTokens.Handle(methodToken);
                if (handle.Kind != HandleKind.MethodDefinition)
                {
                    return(false);
                }

                MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
                if (methodDebugHandle.IsNil)
                {
                    return(false);
                }

                MethodDebugInformation  methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle);
                SequencePointCollection sequencePoints  = methodDebugInfo.GetSequencePoints();

                SequencePoint nearestPoint = sequencePoints.GetEnumerator().Current;
                bool          found        = false;

                foreach (SequencePoint point in sequencePoints)
                {
                    if (found && point.Offset > ilOffset)
                    {
                        break;
                    }

                    if (!point.IsHidden)
                    {
                        nearestPoint = point;
                        found        = true;
                    }
                }

                if (!found || nearestPoint.StartLine == 0)
                {
                    return(false);
                }


                var fileName = reader.GetString(reader.GetDocument(nearestPoint.Document).Name);
                sequencePoint.document    = Marshal.StringToBSTR(fileName);
                sequencePoint.startLine   = nearestPoint.StartLine;
                sequencePoint.startColumn = nearestPoint.StartColumn;
                sequencePoint.endLine     = nearestPoint.EndLine;
                sequencePoint.endColumn   = nearestPoint.EndColumn;
                sequencePoint.offset      = nearestPoint.Offset;
                fileName = null;

                return(true);
            }
            catch
            {
            }
            return(false);
        }
Beispiel #12
0
        public ILStubMethodIL(MethodDesc owningMethod, byte[] ilBytes, LocalVariableDefinition[] locals, Object[] tokens, MethodDebugInformation debugInfo = null)
        {
            _ilBytes  = ilBytes;
            _locals   = locals;
            _tokens   = tokens;
            _method   = owningMethod;
            _maxStack = MaxStackNotSet;

            if (debugInfo == null)
            {
                debugInfo = MethodDebugInformation.None;
            }
            _debugInformation = debugInfo;
        }
Beispiel #13
0
 public void InitializeDebugInfo(MethodDebugInformation debugInfo)
 {
     Debug.Assert(_debugInfo == null);
     _debugInfo = debugInfo;
 }
Beispiel #14
0
 public static List <SequencePoint> GetSequencePointsFromMethodDebugInformation(MethodDebugInformation method)
 {
     return(method.GetSequencePoints().ToList());
 }
Beispiel #15
0
 public void Write(MethodDebugInformation info)
 {
     symbol_writer.Write(info);
 }
Beispiel #16
0
        static Collection <ScopeDebugInformation> ReadScopeAndLocals(PdbScope [] scopes, MethodDebugInformation info)
        {
            var symbols = new Collection <ScopeDebugInformation> (scopes.Length);

            foreach (PdbScope scope in scopes)
            {
                if (scope != null)
                {
                    symbols.Add(ReadScopeAndLocals(scope, info));
                }
            }

            return(symbols);
        }
Beispiel #17
0
        public void CompileMethod(CppMethodCodeNode methodCodeNodeNeedingCode)
        {
            MethodDesc method = methodCodeNodeNeedingCode.Method;

            _compilation.Log.WriteLine("Compiling " + method.ToString());

            if (method.HasCustomAttribute("System.Runtime", "RuntimeImportAttribute"))
            {
                CompileExternMethod(methodCodeNodeNeedingCode, ((EcmaMethod)method).GetRuntimeImportName());
                return;
            }

            if (method.IsRawPInvoke())
            {
                CompileExternMethod(methodCodeNodeNeedingCode, method.GetPInvokeMethodMetadata().Name ?? method.Name);
                return;
            }

            var methodIL = _compilation.GetMethodIL(method);

            if (methodIL == null)
            {
                return;
            }

            try
            {
                var ilImporter = new ILImporter(_compilation, this, method, methodIL);

                CompilerTypeSystemContext typeSystemContext = _compilation.TypeSystemContext;

                MethodDebugInformation debugInfo = _compilation.GetDebugInfo(methodIL);

                if (!_compilation.Options.NoLineNumbers)
                {
                    IEnumerable <ILSequencePoint> sequencePoints = debugInfo.GetSequencePoints();
                    if (sequencePoints != null)
                    {
                        ilImporter.SetSequencePoints(sequencePoints);
                    }
                }

                IEnumerable <ILLocalVariable> localVariables = debugInfo.GetLocalVariables();
                if (localVariables != null)
                {
                    ilImporter.SetLocalVariables(localVariables);
                }

                IEnumerable <string> parameters = GetParameterNamesForMethod(method);
                if (parameters != null)
                {
                    ilImporter.SetParameterNames(parameters);
                }

                ilImporter.Compile(methodCodeNodeNeedingCode);
            }
            catch (Exception e)
            {
                _compilation.Log.WriteLine(e.Message + " (" + method + ")");

                var builder = new CppGenerationBuffer();
                builder.AppendLine();
                builder.Append(GetCppMethodDeclaration(method, true));
                builder.AppendLine();
                builder.Append("{");
                builder.Indent();
                builder.AppendLine();
                builder.Append("throw 0xC000C000;");
                builder.Exdent();
                builder.AppendLine();
                builder.Append("}");

                methodCodeNodeNeedingCode.SetCode(builder.ToString(), Array.Empty <Object>());
            }
        }
Beispiel #18
0
        public MethodIL Link(MethodDesc owningMethod)
        {
            int totalLength       = 0;
            int numSequencePoints = 0;

            for (int i = 0; i < _codeStreams.Count; i++)
            {
                ILCodeStream ilCodeStream = _codeStreams[i];
                ilCodeStream._startOffsetForLinking = totalLength;
                totalLength       += ilCodeStream._length;
                numSequencePoints += ilCodeStream._sequencePoints.Count;
            }

            byte[] ilInstructions = new byte[totalLength];
            int    copiedLength   = 0;

            for (int i = 0; i < _codeStreams.Count; i++)
            {
                ILCodeStream ilCodeStream = _codeStreams[i];
                ilCodeStream.PatchLabels();
                Array.Copy(ilCodeStream._instructions, 0, ilInstructions, copiedLength, ilCodeStream._length);
                copiedLength += ilCodeStream._length;
            }

            MethodDebugInformation debugInfo = null;

            if (numSequencePoints > 0)
            {
                ILSequencePoint[] sequencePoints = new ILSequencePoint[numSequencePoints];
                int copiedSequencePointLength    = 0;
                for (int codeStreamIndex = 0; codeStreamIndex < _codeStreams.Count; codeStreamIndex++)
                {
                    ILCodeStream ilCodeStream = _codeStreams[codeStreamIndex];

                    for (int sequencePointIndex = 0; sequencePointIndex < ilCodeStream._sequencePoints.Count; sequencePointIndex++)
                    {
                        ILSequencePoint sequencePoint = ilCodeStream._sequencePoints[sequencePointIndex];
                        sequencePoints[copiedSequencePointLength] = new ILSequencePoint(
                            ilCodeStream._startOffsetForLinking + sequencePoint.Offset,
                            sequencePoint.Document,
                            sequencePoint.LineNumber);
                        copiedSequencePointLength++;
                    }
                }

                debugInfo = new EmittedMethodDebugInformation(sequencePoints);
            }

            ILExceptionRegion[] exceptionRegions = null;

            int numberOfExceptionRegions = _finallyRegions.Count;

            if (numberOfExceptionRegions > 0)
            {
                exceptionRegions = new ILExceptionRegion[numberOfExceptionRegions];

                for (int i = 0; i < _finallyRegions.Count; i++)
                {
                    ILExceptionRegionBuilder region = _finallyRegions[i];

                    Debug.Assert(region.IsDefined);

                    exceptionRegions[i] = new ILExceptionRegion(ILExceptionRegionKind.Finally,
                                                                region.TryOffset, region.TryLength, region.HandlerOffset, region.HandlerLength,
                                                                classToken: 0, filterOffset: 0);
                }
            }

            var result = new ILStubMethodIL(owningMethod, ilInstructions, _locals.ToArray(), _tokens.ToArray(), exceptionRegions, debugInfo);

            result.CheckStackBalance();
            return(result);
        }
        const int lineNumberIndicatingHiddenLine = 16707566; //0xfeefee

#if NETCOREAPP1_0
        static SequencePoint FirstOrDefaultUnhiddenSequencePoint(MethodDebugInformation body) =>
        body.SequencePoints.FirstOrDefault(sp => sp != null && sp.StartLine != lineNumberIndicatingHiddenLine);
Beispiel #20
0
 public void WriteIteratorScopes(StateMachineScopeDebugInformation state_machine, MethodDebugInformation debug_info)
 {
     Write(CustomMetadataType.IteratorScopes, () => {
         var scopes = state_machine.Scopes;
         writer.WriteInt32(scopes.Count);
         foreach (var scope in scopes)
         {
             var start = scope.Start.Offset;
             var end   = scope.End.IsEndOfMethod ? debug_info.code_size : scope.End.Offset;
             writer.WriteInt32(start);
             writer.WriteInt32(end - 1);
         }
     });
 }
Beispiel #21
0
        public void WriteSequencePoints(MethodDebugInformation info)
        {
            int num  = -1;
            int num2 = -1;

            base.WriteCompressedUInt32(info.local_var_token.RID);
            if (!info.TryGetUniqueDocument(out Document document))
            {
                document = null;
            }
            for (int i = 0; i < info.SequencePoints.Count; i++)
            {
                SequencePoint sequencePoint = info.SequencePoints[i];
                Document      document2     = sequencePoint.Document;
                if (document != document2)
                {
                    MetadataToken documentToken = metadata.GetDocumentToken(document2);
                    if (document != null)
                    {
                        base.WriteCompressedUInt32(0u);
                    }
                    base.WriteCompressedUInt32(documentToken.RID);
                    document = document2;
                }
                if (i > 0)
                {
                    base.WriteCompressedUInt32((uint)(sequencePoint.Offset - info.SequencePoints[i - 1].Offset));
                }
                else
                {
                    base.WriteCompressedUInt32((uint)sequencePoint.Offset);
                }
                if (sequencePoint.IsHidden)
                {
                    base.WriteInt16(0);
                }
                else
                {
                    int num3  = sequencePoint.EndLine - sequencePoint.StartLine;
                    int value = sequencePoint.EndColumn - sequencePoint.StartColumn;
                    base.WriteCompressedUInt32((uint)num3);
                    if (num3 == 0)
                    {
                        base.WriteCompressedUInt32((uint)value);
                    }
                    else
                    {
                        base.WriteCompressedInt32(value);
                    }
                    if (num < 0)
                    {
                        base.WriteCompressedUInt32((uint)sequencePoint.StartLine);
                        base.WriteCompressedUInt32((uint)sequencePoint.StartColumn);
                    }
                    else
                    {
                        base.WriteCompressedInt32(sequencePoint.StartLine - num);
                        base.WriteCompressedInt32(sequencePoint.StartColumn - num2);
                    }
                    num  = sequencePoint.StartLine;
                    num2 = sequencePoint.StartColumn;
                }
            }
        }