5 // Jb Evain (jbevain@novell.com)
7 // (C) 2007 Novell, Inc.
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 // Inspired by the pdb2mdb tool written by Robert Jordan, thanks Robert!
31 namespace Mono.Cecil.Mdb {
34 using System.Collections;
36 using Mono.CompilerServices.SymbolWriter;
41 class MdbWriter : ISymbolWriter {
44 MonoSymbolWriter m_writer;
46 Hashtable m_documents;
48 public MdbWriter (Guid mvid, string assembly)
51 m_writer = new MonoSymbolWriter (assembly);
52 m_documents = new Hashtable ();
55 static Instruction [] GetInstructions (MethodBody body)
57 ArrayList list = new ArrayList ();
58 foreach (Instruction instruction in body.Instructions)
59 if (instruction.SequencePoint != null)
60 list.Add (instruction);
62 return list.ToArray (typeof (Instruction)) as Instruction [];
65 SourceFile GetSourceFile (Document document)
67 string url = document.Url;
68 SourceFile file = m_documents [url] as SourceFile;
72 file = new SourceFile (m_writer.DefineDocument (url));
73 m_documents [url] = file;
77 void Populate (Instruction [] instructions, int [] offsets,
78 int [] startRows, int [] startCols, int [] endRows, int [] endCols,
81 SourceFile document = null;
83 for (int i = 0; i < instructions.Length; i++) {
84 Instruction instr = (Instruction) instructions [i];
85 offsets [i] = instr.Offset;
88 document = GetSourceFile (instr.SequencePoint.Document);
90 startRows [i] = instr.SequencePoint.StartLine;
91 startCols [i] = instr.SequencePoint.StartColumn;
92 endRows [i] = instr.SequencePoint.EndLine;
93 endCols [i] = instr.SequencePoint.EndColumn;
99 public void Write (MethodBody body, byte [][] variables)
101 SourceMethod meth = new SourceMethod (body.Method);
105 Instruction [] instructions = GetInstructions (body);
106 int length = instructions.Length;
110 int [] offsets = new int [length];
111 int [] startRows = new int [length];
112 int [] startCols = new int [length];
113 int [] endRows = new int [length];
114 int [] endCols = new int [length];
116 Populate (instructions, offsets, startRows, startCols, endRows, endCols, out file);
118 m_writer.OpenMethod (file, meth,
119 startRows [0], startCols [0],
120 endRows [length - 1], endCols [length - 1]);
122 for (int i = 0; i < length; i++)
123 m_writer.MarkSequencePoint (offsets [i], startRows [i], startCols [i]);
125 MarkVariables (body, variables);
127 m_writer.CloseMethod ();
130 void MarkVariables (MethodBody body, byte [][] variables)
132 for (int i = 0; i < body.Variables.Count; i++) {
133 VariableDefinition var = body.Variables [i];
134 m_writer.DefineLocalVariable (i, var.Name, variables [i]);
138 public void Dispose ()
140 m_writer.WriteSymbolFile (m_mvid);
143 class SourceFile : ISourceFile {
145 SourceFileEntry m_entry;
147 public SourceFileEntry Entry {
148 get { return m_entry; }
151 public SourceFile (SourceFileEntry entry)
157 class SourceMethod : ISourceMethod {
159 MethodDefinition m_method;
162 get { return m_method.Name; }
165 public int NamespaceID {
170 get { return (int) m_method.MetadataToken.ToUInt (); }
173 public SourceMethod (MethodDefinition method)