Example #1
0
        private void ReadLineNumbers(MethodEntry entry, MethodSymbols symbols)
        {
            LineNumberTable table = entry.GetLineNumberTable();

            LineNumberEntry[] lines = table.LineNumbers;
            Collection <InstructionSymbol> instructions = symbols.instructions = new Collection <InstructionSymbol>(lines.Length);

            for (int i = 0; i < lines.Length; i++)
            {
                LineNumberEntry line = lines[i];
                instructions.Add(new InstructionSymbol(line.Offset, new SequencePoint(this.GetDocument(entry.CompileUnit.SourceFile))
                {
                    StartLine = line.Row,
                    EndLine   = line.Row
                }));
            }
        }
Example #2
0
        void ReadLineNumbers(MethodEntry entry, IDictionary instructions)
        {
            LineNumberTable lnt = entry.GetLineNumberTable();

            foreach (LineNumberEntry line in lnt.LineNumbers)
            {
                Instruction instr = instructions [line.Offset] as Instruction;
                if (instr == null)
                {
                    continue;
                }

                Document doc = GetDocument(entry.CompileUnit.SourceFile);
                instr.SequencePoint           = new SequencePoint(doc);
                instr.SequencePoint.StartLine = line.Row;
                instr.SequencePoint.EndLine   = line.Row;
            }
        }
Example #3
0
        public static AttributeInfo Read(ClassReader classReader, ConstantPool constantPool)
        {
            ushort        attributeNameIndex = classReader.ReadU2();
            string        attributeName      = Encoding.UTF8.GetString(((ConstantUtf8)constantPool.ConstantPoolInfo[attributeNameIndex]).Bytes);
            AttributeInfo attributeInfo      = null;

            switch (attributeName)
            {
            case "ConstantValue":
                attributeInfo = new ConstantValue(); break;

            case "Code":
                attributeInfo = new Code(); break;

            case "Deprecated":
                attributeInfo = new Deprecated(); break;

            case "LineNumberTable":
                attributeInfo = new LineNumberTable(); break;

            case "LocalVariableTable":
                attributeInfo = new LocalVariableTable(); break;

            case "SourceFile":
                attributeInfo = new SourceFile(); break;

            case "Synthetic":
                attributeInfo = new Synthetic(); break;

            case "Exceptions":
                attributeInfo = new Exceptions(); break;

            case "Signature":
                attributeInfo = new Signature(); break;

            //case "StackMapTable":
            //    attributeInfo = null;
            default:
                throw new Exception("no such attribute error");
            }
            attributeInfo.AttributeName = attributeName;
            attributeInfo.ReadAttributeInfo(classReader, constantPool);
            return(attributeInfo);
        }
Example #4
0
        /// <summary>
        /// Provides the method mapping for the specified MDB method.
        /// </summary>
        /// <param name="mdbMethod">The MDB MethodEntry to get the mapping for.</param>
        private MethodMapping GetMapping(MethodEntry mdbMethod)
        {
            var methodMapping = new MethodMapping()
            {
                MethodToken = (uint)mdbMethod.Token,
                SourceFile  = mdbMethod.CompileUnit.SourceFile.FileName
            };

            LineNumberTable lineNumberTable = mdbMethod.GetLineNumberTable();

            if (lineNumberTable != null)
            {
                LineNumberEntry[] lines = lineNumberTable.LineNumbers;

                if (lines != null && lines.Length > 0)
                {
                    methodMapping.StartLine = (uint)lines[0].Row;
                    methodMapping.EndLine   = (uint)lines[lines.Length - 1].Row;
                }
            }

            return(methodMapping);
        }
Example #5
0
        private void ReadLineNumbers(MethodEntry entry, InstructionMapper mapper)
        {
            Document        document = null;
            LineNumberTable table    = entry.GetLineNumberTable();

            LineNumberEntry[] lineNumbers = table.LineNumbers;
            for (int i = 0; i < lineNumbers.Length; i++)
            {
                LineNumberEntry line        = lineNumbers[i];
                Instruction     instruction = mapper(line.Offset);
                if (instruction != null)
                {
                    if (document == null)
                    {
                        document = this.GetDocument(entry.CompileUnit.SourceFile);
                    }
                    instruction.SequencePoint = new SequencePoint(document)
                    {
                        StartLine = line.Row,
                        EndLine   = line.Row
                    };
                }
            }
        }
Example #6
0
        private void GenerateDebugInfo(int prologSize)
        {
            Messages.Verbose("      Generating debug info...");

            sourceFileNameCounter = new Counter <string>();

            Messages.Verbose("        Generating LocalVariableTable...");
            #region LocalVariableTable
            LocalVariableTable varTable = new LocalVariableTable();
            for (int i = 0; i < nextVarIndex; i++)
            {
                LocalVariableTable.LocalVariable varDesc = new LocalVariableTable.LocalVariable();
                varDesc.Index = (ushort)i;

                ILVariable ilVar = var2Index.Where(K => K.Value == i).FirstOrDefault().Key;
                if ((ilVar != null) && (ilVar.Name != ClassNames.VarArgParamName))
                {
                    varDesc.Name = null;
                    if (ilVar.IsGenerated)
                    {
                        varDesc.Name = "gen_" + i.ToString();
                    }
                    else if (ilVar.IsParameter)
                    {
                        varDesc.Name = ilVar.OriginalParameter.Name;
                    }
                    else if (ilVar.OriginalVariable != null)
                    {
                        varDesc.Name = ilVar.OriginalVariable.Name;
                    }
                    if ((varDesc.Name == null) || (varDesc.Name.Length == 0))
                    {
                        varDesc.Name = ilVar.Name ?? "unknown_" + i.ToString();
                    }


                    if (ilVar.Name == "this")
                    {
                        if (thisMethod.DeclaringType.IsPrimitive)
                        {
                            varDesc.Descriptor = "L" + namesController.TypeNameToJava(thisMethod.DeclaringType.CILBoxType) + ";";
                        }
                        else
                        {
                            varDesc.Descriptor = namesController.GetFieldDescriptor(thisMethod.DeclaringType);
                        }
                    }
                    else
                    {
                        varDesc.Descriptor = namesController.GetFieldDescriptor(resolver.Resolve(ilVar.Type, thisMethod.FullGenericArguments));
                    }
                    varDesc.StartPC = 0;
                    varDesc.Length  = (ushort)resultCode.CodeBytes.Length;
                    varTable.Table.Add(varDesc);
                }
                else if ((ilVar != null) && (ilVar.Name == ClassNames.VarArgParamName))
                {
                    varDesc.Name       = ClassNames.VarArgParamName;
                    varDesc.Descriptor = "Ljava/lang/Object;";
                    varDesc.StartPC    = 0;
                    varDesc.Length     = (ushort)resultCode.CodeBytes.Length;
                    varTable.Table.Add(varDesc);
                }
                else
                {
                    var tmpVarsList = tempVars.Where(TV => TV.index == i);

                    int additionalIndex = 0;
                    foreach (var tmpVar in tmpVarsList)
                    {
                        varDesc.Name = "temp_" + i.ToString() + "_" + (additionalIndex++).ToString();
                        switch (tmpVar.type)
                        {
                        case JavaPrimitiveType.Bool: varDesc.Descriptor = "Z"; break;

                        case JavaPrimitiveType.Byte: varDesc.Descriptor = "B"; break;

                        case JavaPrimitiveType.Char: varDesc.Descriptor = "C"; break;

                        case JavaPrimitiveType.Double: varDesc.Descriptor = "D"; break;

                        case JavaPrimitiveType.Float: varDesc.Descriptor = "F"; break;

                        case JavaPrimitiveType.Int: varDesc.Descriptor = "I"; break;

                        case JavaPrimitiveType.Long: varDesc.Descriptor = "J"; break;

                        case JavaPrimitiveType.Short: varDesc.Descriptor = "S"; break;

                        default: varDesc.Descriptor = "Ljava/lang/Object;"; break;
                        }

                        int start = oldCodeGenerator.GetInstructionOffset(tmpVar.startInstr) + prologSize;
                        int end   = resultCode.CodeBytes.Length;
                        if (tmpVar.endInstr >= 0)
                        {
                            end = oldCodeGenerator.GetInstructionOffset(tmpVar.endInstr) + prologSize;
                        }

                        varDesc.StartPC = (ushort)(start);
                        varDesc.Length  = (ushort)(end - start);
                        varTable.Table.Add(varDesc);
                    }
                }
            }
            resultCode.Attributes.Add(varTable);
            #endregion

            Messages.Verbose("        Generating LineNumberTable...");
            #region LineNumberTable
            LineNumberTable linesTable         = new LineNumberTable();
            int             lastLine           = -1;
            var             methodInstructions = thisMethod.Body.Instructions;
            foreach (var i in oldCodeGenerator.EnumerateInstructions())
            {
                ILExpression tag = i.Item2.Tag as ILExpression;
                if (tag == null)
                {
                    continue;
                }
                if ((tag.ILRanges == null) || (tag.ILRanges.Count == 0))
                {
                    continue;
                }

                int minRange = tag.ILRanges.Min(R => R.From);
                int maxRange = tag.ILRanges.Max(R => R.To);

                var ilInstruction = methodInstructions.Where(I => I.Offset >= minRange && I.Offset < maxRange).LastOrDefault();
                if (ilInstruction == null)
                {
                    continue;
                }
                if (ilInstruction.SequencePoint == null)
                {
                    continue;
                }

                int line = ilInstruction.SequencePoint.StartLine;
                sourceFileNameCounter.Add(ilInstruction.SequencePoint.Document.Url);

                if (line == lastLine)
                {
                    continue;
                }

                linesTable.Table.Add(new LineNumberTable.LineNumber((ushort)(i.Item1 + prologSize), (ushort)line));
                lastLine = line;
            }
            resultCode.Attributes.Add(linesTable);
            #endregion
        }
        protected void CheckMethod(MethodEntry method)
        {
            Cecil.MethodDefinition mdef = (Cecil.MethodDefinition)Assembly.MainModule.LookupToken(
                new Cecil.MetadataToken(Cecil.TokenType.Method, method.Token & 0xffffff));
            if ((mdef == null) || (mdef.Body == null))
            {
                throw new MonoSymbolFileException("Method {0} (token {1:x}) not found in assembly.",
                                                  method.Index, method.Token);
            }

            string name = String.Format("{0} ({1})", method.Index, GetMethodName(mdef));

            Debug("[Method {0} - {1} - {2}]", method.Index, method.CompileUnit.SourceFile.FileName,
                  GetMethodName(mdef));

            LineNumberTable lnt = method.GetLineNumberTable();

            if (lnt == null)
            {
                throw new MonoSymbolFileException("Cannot get LNT from method {0}.", name);
            }

            if (lnt.LineNumbers == null)
            {
                throw new MonoSymbolFileException("Cannot get LNT from method {0}.", name);
            }
            LineNumberEntry start, end;

            if (lnt.GetMethodBounds(out start, out end))
            {
                Debug("  Bounds: {0} {1}", start, end);
            }
            foreach (LineNumberEntry line in lnt.LineNumbers)
            {
                Debug("    Line: {0}", line);
            }

            CodeBlockEntry[] blocks = method.GetCodeBlocks() ?? new CodeBlockEntry [0];
            foreach (CodeBlockEntry block in blocks)
            {
                if ((block.Parent >= 0) && (block.Parent >= blocks.Length))
                {
                    throw new MonoSymbolFileException(
                              "Code block {0} in method {1} has invalid parent index {2} (valid is 0..{3}).",
                              block, name, block.Parent, blocks.Length);
                }
            }

            LocalVariableEntry[] locals = method.GetLocals() ?? new LocalVariableEntry [0];
            foreach (LocalVariableEntry local in locals)
            {
                if ((local.BlockIndex < 0) || ((local.BlockIndex > 0) && (local.BlockIndex > blocks.Length)))
                {
                    throw new MonoSymbolFileException(
                              "Local variable {0} in method {1} has invalid block index {2} (valid is 0..{3}).",
                              local, name, local.BlockIndex, blocks.Length);
                }

                Debug("  Local: {0}", local);
            }

            int num_locals = mdef.Body.Variables.Count;

            ScopeVariable[] scope_vars = method.GetScopeVariables() ?? new ScopeVariable [0];
            foreach (ScopeVariable var in scope_vars)
            {
                Debug("  Scope var: {0}", var);
                if ((mdef.IsStatic) && (var.Index < 0))
                {
                    throw new MonoSymbolFileException(
                              "Method {0} has invalid scope variable {1} (referencing `this' in static method).",
                              name, var);
                }
                if ((var.Index >= 0) && (var.Index >= num_locals))
                {
                    throw new MonoSymbolFileException(
                              "Method {0} has invalid scope variable {1} (index out of bounds: {2} / {3}).",
                              name, var, var.Index, num_locals);
                }
                if ((var.Scope > 0) && (File.GetAnonymousScope(var.Scope) == null))
                {
                    throw new MonoSymbolFileException(
                              "Method {0} has invalid scope variable {1} (can't find scope {2}).",
                              name, var, var.Scope);
                }
            }
        }
        public void PrintLineNumberTables()
        {
            Message("Reading {0}, version {1}.{2}.", File.FileName, File.MajorVersion,
                    File.MinorVersion);

            for (int i = 0; i < File.MethodCount; i++)
            {
                if (LineNumberTables.Count > 0)
                {
                    if (!LineNumberTables.ContainsKey(i + 1))
                    {
                        continue;
                    }
                }

                MethodEntry method = File.GetMethod(i + 1);
                if (method == null)
                {
                    throw new MonoSymbolFileException("Cannot get method {0}.", i + 1);
                }

                Cecil.MethodDefinition mdef = (Cecil.MethodDefinition)Assembly.MainModule.LookupToken(
                    new Cecil.MetadataToken(Cecil.TokenType.Method, method.Token & 0xffffff));
                if ((mdef == null) || (mdef.Body == null))
                {
                    throw new MonoSymbolFileException("Method {0} (token {1:x}) not found in assembly.",
                                                      method.Index, method.Token);
                }

                string name = String.Format("{0} ({1})", method.Index, GetMethodName(mdef));
                Message("Method {0} - {1}", method.Index, GetMethodName(mdef));

                LineNumberTable lnt = method.GetLineNumberTable();
                if (lnt == null)
                {
                    throw new MonoSymbolFileException("Cannot get LNT from method {0}.", name);
                }

                if (lnt.LineNumbers == null)
                {
                    throw new MonoSymbolFileException("Cannot get LNT from method {0}.", name);
                }

                Dictionary <int, bool> seen_files = new Dictionary <int, bool> ();

                LineNumberEntry start, end;
                if (lnt.GetMethodBounds(out start, out end))
                {
                    Message("  Bounds: {0} {1}", start, end);
                }
                foreach (LineNumberEntry line in lnt.LineNumbers)
                {
                    if (!line.IsHidden && !seen_files.ContainsKey(line.File))
                    {
                        SourceFileEntry file = File.GetSourceFile(line.File);
                        Message("  File {0}{2}: {1}", file.Index, file.FileName,
                                file.AutoGenerated ? " (auto-generated)" : "");
                        seen_files.Add(line.File, true);
                    }

                    string range = "";
                    if (line.SourceRange != null)
                    {
                        SourceRangeEntry sre = (SourceRangeEntry)line.SourceRange;
                        range = String.Format(" - {0} {1} {2} {3}", sre.StartLine, sre.EndLine,
                                              sre.StartColumn, sre.EndColumn);
                    }

                    Message("    Line {0}:{1}:{2:x}{3}{4}", line.File, line.Row, line.Offset,
                            line.IsHidden ? " (hidden)" : "", range);
                }
            }
        }