X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FMono.Cecil.Mdb%2FMono.Cecil.Mdb%2FMdbWriter.cs;h=eb302a8ac4d31260103c8d828760b78ecf29b76b;hb=c5a3130e48c68ef14107f934d7b27e9edb889946;hp=6e6b5b95e664c86000fb3d24e1335315400a1a83;hpb=0c12a862918170bd80af7bf48e47b9dd0a5766a7;p=mono.git diff --git a/mcs/class/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbWriter.cs b/mcs/class/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbWriter.cs index 6e6b5b95e66..eb302a8ac4d 100644 --- a/mcs/class/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbWriter.cs +++ b/mcs/class/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbWriter.cs @@ -2,9 +2,9 @@ // MdbWriter.cs // // Author: -// Jb Evain (jbevain@gmail.com) +// Jb Evain (jbevain@novell.com) // -// (C) 2006 Jb Evain +// (C) 2007 Novell, Inc. // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -26,146 +26,154 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +// Inspired by the pdb2mdb tool written by Robert Jordan, thanks Robert! + namespace Mono.Cecil.Mdb { + using System; using System.Collections; - using SDS = System.Diagnostics.SymbolStore; + using Mono.CompilerServices.SymbolWriter; + + using Mono.Cecil; using Mono.Cecil.Cil; class MdbWriter : ISymbolWriter { - SymbolWriterImpl m_writer; + Guid m_mvid; + MonoSymbolWriter m_writer; + Hashtable m_documents; - public MdbWriter (SymbolWriterImpl writer) + public MdbWriter (Guid mvid, string assembly) { - m_writer = writer; + m_mvid = mvid; + m_writer = new MonoSymbolWriter (assembly); m_documents = new Hashtable (); } - public void Write (MethodBody body, byte [][] variables) + static Instruction [] GetInstructions (MethodBody body) { - Document document = CreateDocuments (body); - if (document != null) { - SDS.ISymbolDocumentWriter docWriter = GetDocument (document); - m_writer.SetMethodSourceRange (docWriter, 1, 1, docWriter, int.MaxValue, int.MaxValue); - } + ArrayList list = new ArrayList (); + foreach (Instruction instruction in body.Instructions) + if (instruction.SequencePoint != null) + list.Add (instruction); - m_writer.OpenMethod (new SDS.SymbolToken ((int) body.Method.MetadataToken.ToUInt ())); - m_writer.SetSymAttribute (new SDS.SymbolToken (), "__name", System.Text.Encoding.UTF8.GetBytes (body.Method.Name)); + return list.ToArray (typeof (Instruction)) as Instruction []; + } - CreateScopes (body, body.Scopes, variables); - m_writer.CloseMethod (); + SourceFile GetSourceFile (Document document) + { + string url = document.Url; + SourceFile file = m_documents [url] as SourceFile; + if (file != null) + return file; + + file = new SourceFile (m_writer.DefineDocument (url)); + m_documents [url] = file; + return file; } - void CreateScopes (MethodBody body, ScopeCollection scopes, byte [][] variables) + void Populate (Instruction [] instructions, int [] offsets, + int [] startRows, int [] startCols, int [] endRows, int [] endCols, + out SourceFile file) { - foreach (Scope s in scopes) { - int startOffset = s.Start.Offset; - int endOffset = s.End == body.Instructions.Outside ? - body.Instructions[body.Instructions.Count - 1].Offset + 1 : - s.End.Offset; + SourceFile document = null; + + for (int i = 0; i < instructions.Length; i++) { + Instruction instr = (Instruction) instructions [i]; + offsets [i] = instr.Offset; - m_writer.OpenScope (startOffset); - m_writer.UsingNamespace (body.Method.DeclaringType.Namespace); - m_writer.OpenNamespace (body.Method.DeclaringType.Namespace); + if (document == null) + document = GetSourceFile (instr.SequencePoint.Document); - int start = body.Instructions.IndexOf (s.Start); - int end = s.End == body.Instructions.Outside ? - body.Instructions.Count - 1 : - body.Instructions.IndexOf (s.End); + startRows [i] = instr.SequencePoint.StartLine; + startCols [i] = instr.SequencePoint.StartColumn; + endRows [i] = instr.SequencePoint.EndLine; + endCols [i] = instr.SequencePoint.EndColumn; + } - ArrayList instructions = new ArrayList(); - for (int i = start; i <= end; i++) - if (body.Instructions [i].SequencePoint != null) - instructions.Add (body.Instructions [i]); + file = document; + } - Document doc = null; + public void Write (MethodBody body, byte [][] variables) + { + SourceMethod meth = new SourceMethod (body.Method); - int [] offsets = new int [instructions.Count]; - int [] startRows = new int [instructions.Count]; - int [] startCols = new int [instructions.Count]; - int [] endRows = new int [instructions.Count]; - int [] endCols = new int [instructions.Count]; + SourceFile file; - for (int i = 0; i < instructions.Count; i++) { - Instruction instr = (Instruction) instructions [i]; - offsets [i] = instr.Offset; + Instruction [] instructions = GetInstructions (body); + int length = instructions.Length; + if (length == 0) + return; - if (doc == null) - doc = instr.SequencePoint.Document; + int [] offsets = new int [length]; + int [] startRows = new int [length]; + int [] startCols = new int [length]; + int [] endRows = new int [length]; + int [] endCols = new int [length]; - startRows [i] = instr.SequencePoint.StartLine; - startCols [i] = instr.SequencePoint.StartColumn; - endRows [i] = instr.SequencePoint.EndLine; - endCols [i] = instr.SequencePoint.EndColumn; - } + Populate (instructions, offsets, startRows, startCols, endRows, endCols, out file); - m_writer.DefineSequencePoints (GetDocument (doc), - offsets, startRows, startCols, endRows, endCols); + m_writer.OpenMethod (file, meth, + startRows [0], startCols [0], + endRows [length - 1], endCols [length - 1]); - CreateLocalVariables (s, startOffset, endOffset, variables); + for (int i = 0; i < length; i++) + m_writer.MarkSequencePoint (offsets [i], startRows [i], startCols [i]); - CreateScopes (body, s.Scopes, variables); - m_writer.CloseNamespace (); + MarkVariables (body, variables); - m_writer.CloseScope (endOffset); - } + m_writer.CloseMethod (); } - void CreateLocalVariables (Scope s, int startOffset, int endOffset, byte [][] variables) + void MarkVariables (MethodBody body, byte [][] variables) { - for (int i = 0; i < s.Variables.Count; i++) { - VariableDefinition var = s.Variables [i]; - m_writer.DefineLocalVariable ( - var.Name, - 0, - variables [var.Index], - 0, - 0, - 0, - 0, - startOffset, - endOffset); + for (int i = 0; i < body.Variables.Count; i++) { + VariableDefinition var = body.Variables [i]; + m_writer.DefineLocalVariable (i, var.Name, variables [i]); } } - Document CreateDocuments (MethodBody body) + public void Dispose () { - Document doc = null; - foreach (Instruction instr in body.Instructions) { - if (instr.SequencePoint == null) - continue; + m_writer.WriteSymbolFile (m_mvid); + } - if (doc == null) - doc = instr.SequencePoint.Document; + class SourceFile : ISourceFile { - GetDocument (instr.SequencePoint.Document); + SourceFileEntry m_entry; + + public SourceFileEntry Entry { + get { return m_entry; } } - return doc; + public SourceFile (SourceFileEntry entry) + { + m_entry = entry; + } } - SDS.ISymbolDocumentWriter GetDocument (Document document) - { - SDS.ISymbolDocumentWriter docWriter = m_documents [document.Url] as SDS.ISymbolDocumentWriter; - if (docWriter != null) - return docWriter; - - docWriter = m_writer.DefineDocument ( - document.Url, - GuidAttribute.GetGuidFromValue ((int) document.Language, typeof (DocumentLanguage)), - GuidAttribute.GetGuidFromValue ((int) document.LanguageVendor, typeof (DocumentLanguageVendor)), - GuidAttribute.GetGuidFromValue ((int) document.Type, typeof (DocumentType))); - - m_documents [document.Url] = docWriter; - return docWriter; - } + class SourceMethod : ISourceMethod { - public void Dispose () - { - m_writer.Close (); + MethodDefinition m_method; + + public string Name { + get { return m_method.Name; } + } + + public int NamespaceID { + get { return 0; } + } + + public int Token { + get { return (int) m_method.MetadataToken.ToUInt (); } + } + + public SourceMethod (MethodDefinition method) + { + m_method = method; + } } } }