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 })); } }
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; } }
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); }
/// <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); }
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 }; } } }
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); } } }