5
// Jb Evain (jbevain@gmail.com)
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
namespace Mono.Cecil.Mdb {
31
using System.Collections;
35
using Mono.CompilerServices.SymbolWriter;
37
class MdbReader : ISymbolReader {
39
MonoSymbolFile m_symFile;
40
Hashtable m_documents;
43
public MdbReader (MonoSymbolFile symFile)
46
m_documents = new Hashtable ();
47
m_scopes = new Hashtable ();
50
Hashtable GetInstructions (MethodBody body)
52
Hashtable instructions = new Hashtable (body.Instructions.Count);
53
foreach (Instruction i in body.Instructions)
54
instructions.Add (i.Offset, i);
59
Instruction GetInstruction (MethodBody body, Hashtable instructions, int offset)
61
Instruction instr = (Instruction) instructions [offset];
65
return body.Instructions.Outside;
68
public void Read (MethodBody body)
70
MethodEntry entry = m_symFile.GetMethodByToken ((int) body.Method.MetadataToken.ToUInt ());
74
Hashtable instructions = GetInstructions(body);
75
ReadScopes (entry, body, instructions);
76
ReadLineNumbers (entry, instructions);
77
ReadLocalVariables (entry, body);
80
void ReadLocalVariables (MethodEntry entry, MethodBody body)
82
foreach (LocalVariableEntry loc in entry.Locals) {
83
Scope scope = m_scopes [loc.BlockIndex] as Scope;
87
VariableDefinition var = body.Variables [loc.Index];
89
scope.Variables.Add (var);
93
void ReadLineNumbers (MethodEntry entry, Hashtable instructions)
95
foreach (LineNumberEntry line in entry.LineNumbers) {
96
Instruction instr = instructions [line.Offset] as Instruction;
100
Document doc = GetDocument (entry.SourceFile);
101
instr.SequencePoint = new SequencePoint (doc);
102
instr.SequencePoint.StartLine = line.Row;
103
instr.SequencePoint.EndLine = line.Row;
107
Document GetDocument (SourceFileEntry file)
109
Document doc = m_documents [file.FileName] as Document;
113
doc = new Document (file.FileName);
115
m_documents [file.FileName] = doc;
119
void ReadScopes (MethodEntry entry, MethodBody body, Hashtable instructions)
121
foreach (LexicalBlockEntry scope in entry.LexicalBlocks) {
122
Scope s = new Scope ();
123
s.Start = GetInstruction (body, instructions, scope.StartOffset);
124
s.End = GetInstruction(body, instructions, scope.EndOffset);
125
m_scopes [scope.Index] = s;
127
if (!AddScope (body, s))
132
bool AddScope (IScopeProvider provider, Scope s)
134
foreach (Scope scope in provider.Scopes) {
135
if (AddScope (scope, s))
138
if (s.Start.Offset >= scope.Start.Offset && s.End.Offset <= scope.End.Offset) {
139
scope.Scopes.Add (s);
147
public void Dispose ()
149
m_symFile.Dispose ();