5 // Jb Evain (jbevain@gmail.com)
7 // Copyright (c) 2008 - 2011 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 internal MethodSymbols (string methodName)
156 this.method_name = methodName;
159 public MethodSymbols (MetadataToken methodToken)
161 this.method_token = methodToken;
165 public delegate Instruction InstructionMapper (int offset);
167 public interface ISymbolReader : IDisposable {
169 bool ProcessDebugHeader (ImageDebugDirectory directory, byte [] header);
170 void Read (MethodBody body, InstructionMapper mapper);
171 void Read (MethodSymbols symbols);
174 public interface ISymbolReaderProvider {
176 ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName);
177 ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream);
180 static class SymbolProvider {
182 static readonly string symbol_kind = Type.GetType ("Mono.Runtime") != null ? "Mdb" : "Pdb";
184 static SR.AssemblyName GetPlatformSymbolAssemblyName ()
186 var cecil_name = typeof (SymbolProvider).Assembly.GetName ();
188 var name = new SR.AssemblyName {
189 Name = "Mono.Cecil." + symbol_kind,
190 Version = cecil_name.Version,
193 name.SetPublicKeyToken (cecil_name.GetPublicKeyToken ());
198 static Type GetPlatformType (string fullname)
200 var type = Type.GetType (fullname);
204 var assembly_name = GetPlatformSymbolAssemblyName ();
206 type = Type.GetType (fullname + ", " + assembly_name.FullName);
211 var assembly = SR.Assembly.Load (assembly_name);
212 if (assembly != null)
213 return assembly.GetType (fullname);
214 } catch (FileNotFoundException) {
216 } catch (FileLoadException) {
223 static ISymbolReaderProvider reader_provider;
225 public static ISymbolReaderProvider GetPlatformReaderProvider ()
227 if (reader_provider != null)
228 return reader_provider;
230 var type = GetPlatformType (GetProviderTypeName ("ReaderProvider"));
234 return reader_provider = (ISymbolReaderProvider) Activator.CreateInstance (type);
237 static string GetProviderTypeName (string name)
239 return "Mono.Cecil." + symbol_kind + "." + symbol_kind + name;
244 static ISymbolWriterProvider writer_provider;
246 public static ISymbolWriterProvider GetPlatformWriterProvider ()
248 if (writer_provider != null)
249 return writer_provider;
251 var type = GetPlatformType (GetProviderTypeName ("WriterProvider"));
255 return writer_provider = (ISymbolWriterProvider) Activator.CreateInstance (type);
263 public interface ISymbolWriter : IDisposable {
265 bool GetDebugHeader (out ImageDebugDirectory directory, out byte [] header);
266 void Write (MethodBody body);
267 void Write (MethodSymbols symbols);
270 public interface ISymbolWriterProvider {
272 ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName);
273 ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream);