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)