5
// Jb Evain (jbevain@gmail.com)
7
// Copyright (c) 2008 - 2010 Jb Evain
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.
31
using System.Runtime.InteropServices;
32
using SR = System.Reflection;
34
using Mono.Collections.Generic;
36
namespace Mono.Cecil.Cil {
38
[StructLayout (LayoutKind.Sequential)]
39
public struct ImageDebugDirectory {
40
public int Characteristics;
41
public int TimeDateStamp;
42
public short MajorVersion;
43
public short MinorVersion;
45
public int SizeOfData;
46
public int AddressOfRawData;
47
public int PointerToRawData;
50
public sealed class Scope : IVariableDefinitionProvider {
55
Collection<Scope> scopes;
56
Collection<VariableDefinition> variables;
58
public Instruction Start {
60
set { start = value; }
63
public Instruction End {
68
public bool HasScopes {
69
get { return !scopes.IsNullOrEmpty (); }
72
public Collection<Scope> Scopes {
75
scopes = new Collection<Scope> ();
81
public bool HasVariables {
82
get { return !variables.IsNullOrEmpty (); }
85
public Collection<VariableDefinition> Variables {
87
if (variables == null)
88
variables = new Collection<VariableDefinition> ();
95
public struct InstructionSymbol {
97
public readonly int Offset;
98
public readonly SequencePoint SequencePoint;
100
public InstructionSymbol (int offset, SequencePoint sequencePoint)
102
this.Offset = offset;
103
this.SequencePoint = sequencePoint;
107
public sealed class MethodSymbols {
109
internal int code_size;
110
internal string method_name;
111
internal MetadataToken method_token;
112
internal MetadataToken local_var_token;
113
internal Collection<VariableDefinition> variables;
114
internal Collection<InstructionSymbol> instructions;
116
public bool HasVariables {
117
get { return !variables.IsNullOrEmpty (); }
120
public Collection<VariableDefinition> Variables {
122
if (variables == null)
123
variables = new Collection<VariableDefinition> ();
129
public Collection<InstructionSymbol> Instructions {
131
if (instructions == null)
132
instructions = new Collection<InstructionSymbol> ();
138
public int CodeSize {
139
get { return code_size; }
142
public string MethodName {
143
get { return method_name; }
146
public MetadataToken MethodToken {
147
get { return method_token; }
150
public MetadataToken LocalVarToken {
151
get { return local_var_token; }
154
public MethodSymbols (string methodName)
156
this.method_name = methodName;
160
public delegate Instruction InstructionMapper (int offset);
162
public interface ISymbolReader : IDisposable {
164
bool ProcessDebugHeader (ImageDebugDirectory directory, byte [] header);
165
void Read (MethodBody body, InstructionMapper mapper);
166
void Read (MethodSymbols symbols);
169
public interface ISymbolReaderProvider {
171
ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName);
172
ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream);
175
static class SymbolProvider {
177
static readonly string symbol_kind = Type.GetType ("Mono.Runtime") != null ? "Mdb" : "Pdb";
179
static SR.AssemblyName GetPlatformSymbolAssemblyName ()
181
var cecil_name = typeof (SymbolProvider).Assembly.GetName ();
183
var name = new SR.AssemblyName {
184
Name = "Mono.Cecil." + symbol_kind,
185
Version = cecil_name.Version,
188
name.SetPublicKeyToken (cecil_name.GetPublicKeyToken ());
193
static Type GetPlatformType (string fullname)
195
var type = Type.GetType (fullname);
199
var assembly_name = GetPlatformSymbolAssemblyName ();
201
type = Type.GetType (fullname + ", " + assembly_name.FullName);
206
var assembly = SR.Assembly.Load (assembly_name);
207
if (assembly != null)
208
return assembly.GetType (fullname);
209
} catch (FileNotFoundException) {
211
} catch (FileLoadException) {
218
static ISymbolReaderProvider reader_provider;
220
public static ISymbolReaderProvider GetPlatformReaderProvider ()
222
if (reader_provider != null)
223
return reader_provider;
225
var type = GetPlatformType (GetProviderTypeName ("ReaderProvider"));
229
return reader_provider = (ISymbolReaderProvider) Activator.CreateInstance (type);
232
static string GetProviderTypeName (string name)
234
return "Mono.Cecil." + symbol_kind + "." + symbol_kind + name;
239
static ISymbolWriterProvider writer_provider;
241
public static ISymbolWriterProvider GetPlatformWriterProvider ()
243
if (writer_provider != null)
244
return writer_provider;
246
var type = GetPlatformType (GetProviderTypeName ("WriterProvider"));
250
return writer_provider = (ISymbolWriterProvider) Activator.CreateInstance (type);
258
public interface ISymbolWriter : IDisposable {
260
bool GetDebugHeader (out ImageDebugDirectory directory, out byte [] header);
261
void Write (MethodBody body);
262
void Write (MethodSymbols symbols);
265
public interface ISymbolWriterProvider {
267
ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName);
268
ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream);