| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174 | 
							- //
 
- // Author:
 
- //   Jb Evain (jbevain@gmail.com)
 
- //
 
- // Copyright (c) 2008 - 2015 Jb Evain
 
- // Copyright (c) 2008 - 2011 Novell, Inc.
 
- //
 
- // Licensed under the MIT/X11 license.
 
- //
 
- using System;
 
- using System.Collections.Generic;
 
- using System.IO;
 
- using System.Runtime.InteropServices;
 
- using System.Threading;
 
- using SR = System.Reflection;
 
- using ILRuntime.Mono.Collections.Generic;
 
- using ILRuntime.Mono.Cecil.Cil;
 
- using ILRuntime.Mono.Cecil.PE;
 
- namespace ILRuntime.Mono.Cecil.Cil {
 
- 	[StructLayout (LayoutKind.Sequential)]
 
- 	public struct ImageDebugDirectory {
 
- 		public const int Size = 28;
 
- 		public int Characteristics;
 
- 		public int TimeDateStamp;
 
- 		public short MajorVersion;
 
- 		public short MinorVersion;
 
- 		public ImageDebugType Type;
 
- 		public int SizeOfData;
 
- 		public int AddressOfRawData;
 
- 		public int PointerToRawData;
 
- 	}
 
- 	public enum ImageDebugType {
 
- 		CodeView = 2,
 
- 		Deterministic = 16,
 
- 		EmbeddedPortablePdb = 17,
 
- 	}
 
- 	public sealed class ImageDebugHeader {
 
- 		readonly ImageDebugHeaderEntry [] entries;
 
- 		public bool HasEntries {
 
- 			get { return !entries.IsNullOrEmpty (); }
 
- 		}
 
- 		public ImageDebugHeaderEntry [] Entries {
 
- 			get { return entries; }
 
- 		}
 
- 		public ImageDebugHeader (ImageDebugHeaderEntry [] entries)
 
- 		{
 
- 			this.entries = entries ?? Empty<ImageDebugHeaderEntry>.Array;
 
- 		}
 
- 		public ImageDebugHeader ()
 
- 			: this (Empty<ImageDebugHeaderEntry>.Array)
 
- 		{
 
- 		}
 
- 		public ImageDebugHeader (ImageDebugHeaderEntry entry)
 
- 			: this (new [] { entry })
 
- 		{
 
- 		}
 
- 	}
 
- 	public sealed class ImageDebugHeaderEntry {
 
- 		ImageDebugDirectory directory;
 
- 		readonly byte [] data;
 
- 		public ImageDebugDirectory Directory {
 
- 			get { return directory; }
 
- 			internal set { directory = value; }
 
- 		}
 
- 		public byte [] Data {
 
- 			get { return data; }
 
- 		}
 
- 		public ImageDebugHeaderEntry (ImageDebugDirectory directory, byte [] data)
 
- 		{
 
- 			this.directory = directory;
 
- 			this.data = data ?? Empty<byte>.Array;
 
- 		}
 
- 	}
 
- 	public sealed class ScopeDebugInformation : DebugInformation {
 
- 		internal InstructionOffset start;
 
- 		internal InstructionOffset end;
 
- 		internal ImportDebugInformation import;
 
- 		internal Collection<ScopeDebugInformation> scopes;
 
- 		internal Collection<VariableDebugInformation> variables;
 
- 		internal Collection<ConstantDebugInformation> constants;
 
- 		public InstructionOffset Start {
 
- 			get { return start; }
 
- 			set { start = value; }
 
- 		}
 
- 		public InstructionOffset End {
 
- 			get { return end; }
 
- 			set { end = value; }
 
- 		}
 
- 		public ImportDebugInformation Import {
 
- 			get { return import; }
 
- 			set { import = value; }
 
- 		}
 
- 		public bool HasScopes {
 
- 			get { return !scopes.IsNullOrEmpty (); }
 
- 		}
 
- 		public Collection<ScopeDebugInformation> Scopes {
 
- 			get {
 
- 				if (scopes == null)
 
- 					Interlocked.CompareExchange (ref scopes, new Collection<ScopeDebugInformation> (), null);
 
- 				return scopes;
 
- 			}
 
- 		}
 
- 		public bool HasVariables {
 
- 			get { return !variables.IsNullOrEmpty (); }
 
- 		}
 
- 		public Collection<VariableDebugInformation> Variables {
 
- 			get {
 
- 				if (variables == null)
 
- 					Interlocked.CompareExchange (ref variables, new Collection<VariableDebugInformation> (), null);
 
- 				return variables;
 
- 			}
 
- 		}
 
- 		public bool HasConstants {
 
- 			get { return !constants.IsNullOrEmpty (); }
 
- 		}
 
- 		public Collection<ConstantDebugInformation> Constants {
 
- 			get {
 
- 				if (constants == null)
 
- 					Interlocked.CompareExchange (ref constants, new Collection<ConstantDebugInformation> (), null);
 
- 				return constants;
 
- 			}
 
- 		}
 
- 		internal ScopeDebugInformation ()
 
- 		{
 
- 			this.token = new MetadataToken (TokenType.LocalScope);
 
- 		}
 
- 		public ScopeDebugInformation (Instruction start, Instruction end)
 
- 			: this ()
 
- 		{
 
- 			if (start == null)
 
- 				throw new ArgumentNullException ("start");
 
- 			this.start = new InstructionOffset (start);
 
- 			if (end != null)
 
- 				this.end = new InstructionOffset (end);
 
- 		}
 
- 		public bool TryGetName (VariableDefinition variable, out string name)
 
- 		{
 
- 			name = null;
 
- 			if (variables == null || variables.Count == 0)
 
- 				return false;
 
- 			for (int i = 0; i < variables.Count; i++) {
 
- 				if (variables [i].Index == variable.Index) {
 
- 					name = variables [i].Name;
 
- 					return true;
 
- 				}
 
- 			}
 
- 			return false;
 
- 		}
 
- 	}
 
- 	public struct InstructionOffset {
 
- 		readonly Instruction instruction;
 
- 		readonly int? offset;
 
- 		public int Offset {
 
- 			get {
 
- 				if (instruction != null)
 
- 					return instruction.Offset;
 
- 				if (offset.HasValue)
 
- 					return offset.Value;
 
- 				throw new NotSupportedException ();
 
- 			}
 
- 		}
 
- 		public bool IsEndOfMethod {
 
- 			get { return instruction == null && !offset.HasValue; }
 
- 		}
 
- 		internal bool IsResolved => instruction != null || !offset.HasValue;
 
- 		internal Instruction ResolvedInstruction => instruction;
 
- 		public InstructionOffset (Instruction instruction)
 
- 		{
 
- 			if (instruction == null)
 
- 				throw new ArgumentNullException ("instruction");
 
- 			this.instruction = instruction;
 
- 			this.offset = null;
 
- 		}
 
- 		public InstructionOffset (int offset)
 
- 		{
 
- 			this.instruction = null;
 
- 			this.offset = offset;
 
- 		}
 
- 	}
 
- 	[Flags]
 
- 	public enum VariableAttributes : ushort {
 
- 		None = 0,
 
- 		DebuggerHidden = 1,
 
- 	}
 
- 	public struct VariableIndex {
 
- 		readonly VariableDefinition variable;
 
- 		readonly int? index;
 
- 		public int Index {
 
- 			get {
 
- 				if (variable != null)
 
- 					return variable.Index;
 
- 				if (index.HasValue)
 
- 					return index.Value;
 
- 				throw new NotSupportedException ();
 
- 			}
 
- 		}
 
- 		internal bool IsResolved => variable != null;
 
- 		internal VariableDefinition ResolvedVariable => variable;
 
- 		public VariableIndex (VariableDefinition variable)
 
- 		{
 
- 			if (variable == null)
 
- 				throw new ArgumentNullException ("variable");
 
- 			this.variable = variable;
 
- 			this.index = null;
 
- 		}
 
- 		public VariableIndex (int index)
 
- 		{
 
- 			this.variable = null;
 
- 			this.index = index;
 
- 		}
 
- 	}
 
- 	public abstract class DebugInformation : ICustomDebugInformationProvider {
 
- 		internal MetadataToken token;
 
- 		internal Collection<CustomDebugInformation> custom_infos;
 
- 		public MetadataToken MetadataToken {
 
- 			get { return token; }
 
- 			set { token = value; }
 
- 		}
 
- 		public bool HasCustomDebugInformations {
 
- 			get { return !custom_infos.IsNullOrEmpty (); }
 
- 		}
 
- 		public Collection<CustomDebugInformation> CustomDebugInformations {
 
- 			get {
 
- 				if (custom_infos == null)
 
- 					Interlocked.CompareExchange (ref custom_infos, new Collection<CustomDebugInformation> (), null);
 
- 				return custom_infos;
 
- 			}
 
- 		}
 
- 		internal DebugInformation ()
 
- 		{
 
- 		}
 
- 	}
 
- 	public sealed class VariableDebugInformation : DebugInformation {
 
- 		string name;
 
- 		ushort attributes;
 
- 		internal VariableIndex index;
 
- 		public int Index {
 
- 			get { return index.Index; }
 
- 		}
 
- 		public string Name {
 
- 			get { return name; }
 
- 			set { name = value; }
 
- 		}
 
- 		public VariableAttributes Attributes {
 
- 			get { return (VariableAttributes) attributes; }
 
- 			set { attributes = (ushort) value; }
 
- 		}
 
- 		public bool IsDebuggerHidden {
 
- 			get { return attributes.GetAttributes ((ushort) VariableAttributes.DebuggerHidden); }
 
- 			set { attributes = attributes.SetAttributes ((ushort) VariableAttributes.DebuggerHidden, value); }
 
- 		}
 
- 		internal VariableDebugInformation (int index, string name)
 
- 		{
 
- 			if (name == null)
 
- 				throw new ArgumentNullException ("name");
 
- 			this.index = new VariableIndex (index);
 
- 			this.name = name;
 
- 		}
 
- 		public VariableDebugInformation (VariableDefinition variable, string name)
 
- 		{
 
- 			if (variable == null)
 
- 				throw new ArgumentNullException ("variable");
 
- 			if (name == null)
 
- 				throw new ArgumentNullException ("name");
 
- 			this.index = new VariableIndex (variable);
 
- 			this.name = name;
 
- 			this.token = new MetadataToken (TokenType.LocalVariable);
 
- 		}
 
- 	}
 
- 	public sealed class ConstantDebugInformation : DebugInformation {
 
- 		string name;
 
- 		TypeReference constant_type;
 
- 		object value;
 
- 		public string Name {
 
- 			get { return name; }
 
- 			set { name = value; }
 
- 		}
 
- 		public TypeReference ConstantType {
 
- 			get { return constant_type; }
 
- 			set { constant_type = value; }
 
- 		}
 
- 		public object Value {
 
- 			get { return value; }
 
- 			set { this.value = value; }
 
- 		}
 
- 		public ConstantDebugInformation (string name, TypeReference constant_type, object value)
 
- 		{
 
- 			if (name == null)
 
- 				throw new ArgumentNullException ("name");
 
- 			this.name = name;
 
- 			this.constant_type = constant_type;
 
- 			this.value = value;
 
- 			this.token = new MetadataToken (TokenType.LocalConstant);
 
- 		}
 
- 	}
 
- 	public enum ImportTargetKind : byte {
 
- 		ImportNamespace = 1,
 
- 		ImportNamespaceInAssembly = 2,
 
- 		ImportType = 3,
 
- 		ImportXmlNamespaceWithAlias = 4,
 
- 		ImportAlias = 5,
 
- 		DefineAssemblyAlias = 6,
 
- 		DefineNamespaceAlias = 7,
 
- 		DefineNamespaceInAssemblyAlias = 8,
 
- 		DefineTypeAlias = 9,
 
- 	}
 
- 	public sealed class ImportTarget {
 
- 		internal ImportTargetKind kind;
 
- 		internal string @namespace;
 
- 		internal TypeReference type;
 
- 		internal AssemblyNameReference reference;
 
- 		internal string alias;
 
- 		public string Namespace {
 
- 			get { return @namespace; }
 
- 			set { @namespace = value; }
 
- 		}
 
- 		public TypeReference Type {
 
- 			get { return type; }
 
- 			set { type = value; }
 
- 		}
 
- 		public AssemblyNameReference AssemblyReference {
 
- 			get { return reference; }
 
- 			set { reference = value; }
 
- 		}
 
- 		public string Alias {
 
- 			get { return alias; }
 
- 			set { alias = value; }
 
- 		}
 
- 		public ImportTargetKind Kind {
 
- 			get { return kind; }
 
- 			set { kind = value; }
 
- 		}
 
- 		public ImportTarget (ImportTargetKind kind)
 
- 		{
 
- 			this.kind = kind;
 
- 		}
 
- 	}
 
- 	public sealed class ImportDebugInformation : DebugInformation {
 
- 		internal ImportDebugInformation parent;
 
- 		internal Collection<ImportTarget> targets;
 
- 		public bool HasTargets {
 
- 			get { return !targets.IsNullOrEmpty (); }
 
- 		}
 
- 		public Collection<ImportTarget> Targets {
 
- 			get
 
- 			{
 
- 				if (targets == null)
 
- 					Interlocked.CompareExchange (ref targets, new Collection<ImportTarget> (), null);
 
- 				return targets;
 
- 			}
 
- 		}
 
- 		public ImportDebugInformation Parent {
 
- 			get { return parent; }
 
- 			set { parent = value; }
 
- 		}
 
- 		public ImportDebugInformation ()
 
- 		{
 
- 			this.token = new MetadataToken (TokenType.ImportScope);
 
- 		}
 
- 	}
 
- 	public interface ICustomDebugInformationProvider : IMetadataTokenProvider {
 
- 		bool HasCustomDebugInformations { get; }
 
- 		Collection<CustomDebugInformation> CustomDebugInformations { get; }
 
- 	}
 
- 	public enum CustomDebugInformationKind {
 
- 		Binary,
 
- 		StateMachineScope,
 
- 		DynamicVariable,
 
- 		DefaultNamespace,
 
- 		AsyncMethodBody,
 
- 		EmbeddedSource,
 
- 		SourceLink,
 
- 	}
 
- 	public abstract class CustomDebugInformation : DebugInformation {
 
- 		Guid identifier;
 
- 		public Guid Identifier {
 
- 			get { return identifier; }
 
- 		}
 
- 		public abstract CustomDebugInformationKind Kind { get; }
 
- 		internal CustomDebugInformation (Guid identifier)
 
- 		{
 
- 			this.identifier = identifier;
 
- 			this.token = new MetadataToken (TokenType.CustomDebugInformation);
 
- 		}
 
- 	}
 
- 	public sealed class BinaryCustomDebugInformation : CustomDebugInformation {
 
- 		byte [] data;
 
- 		public byte [] Data {
 
- 			get { return data; }
 
- 			set { data = value; }
 
- 		}
 
- 		public override CustomDebugInformationKind Kind {
 
- 			get { return CustomDebugInformationKind.Binary; }
 
- 		}
 
- 		public BinaryCustomDebugInformation (Guid identifier, byte [] data)
 
- 			: base (identifier)
 
- 		{
 
- 			this.data = data;
 
- 		}
 
- 	}
 
- 	public sealed class AsyncMethodBodyDebugInformation : CustomDebugInformation {
 
- 		internal InstructionOffset catch_handler;
 
- 		internal Collection<InstructionOffset> yields;
 
- 		internal Collection<InstructionOffset> resumes;
 
- 		internal Collection<MethodDefinition> resume_methods;
 
- 		public InstructionOffset CatchHandler {
 
- 			get { return catch_handler; }
 
- 			set { catch_handler = value; }
 
- 		}
 
- 		public Collection<InstructionOffset> Yields {
 
- 			get {
 
- 				if (yields == null)
 
- 					Interlocked.CompareExchange (ref yields, new Collection<InstructionOffset> (), null);
 
- 				return yields;
 
- 			}
 
- 		}
 
- 		public Collection<InstructionOffset> Resumes {
 
- 			get {
 
- 				if (resumes == null)
 
- 					Interlocked.CompareExchange (ref resumes, new Collection<InstructionOffset> (), null);
 
- 				return resumes;
 
- 			}
 
- 		}
 
- 		public Collection<MethodDefinition> ResumeMethods {
 
- 			get { return resume_methods ?? (resume_methods = new Collection<MethodDefinition> ()); }
 
- 		}
 
- 		public override CustomDebugInformationKind Kind {
 
- 			get { return CustomDebugInformationKind.AsyncMethodBody; }
 
- 		}
 
- 		public static Guid KindIdentifier = new Guid ("{54FD2AC5-E925-401A-9C2A-F94F171072F8}");
 
- 		internal AsyncMethodBodyDebugInformation (int catchHandler)
 
- 			: base (KindIdentifier)
 
- 		{
 
- 			this.catch_handler = new InstructionOffset (catchHandler);
 
- 		}
 
- 		public AsyncMethodBodyDebugInformation (Instruction catchHandler)
 
- 			: base (KindIdentifier)
 
- 		{
 
- 			this.catch_handler = new InstructionOffset (catchHandler);
 
- 		}
 
- 		public AsyncMethodBodyDebugInformation ()
 
- 			: base (KindIdentifier)
 
- 		{
 
- 			this.catch_handler = new InstructionOffset (-1);
 
- 		}
 
- 	}
 
- 	public sealed class StateMachineScope {
 
- 		internal InstructionOffset start;
 
- 		internal InstructionOffset end;
 
- 		public InstructionOffset Start {
 
- 			get { return start; }
 
- 			set { start = value; }
 
- 		}
 
- 		public InstructionOffset End {
 
- 			get { return end; }
 
- 			set { end = value; }
 
- 		}
 
- 		internal StateMachineScope (int start, int end)
 
- 		{
 
- 			this.start = new InstructionOffset (start);
 
- 			this.end = new InstructionOffset (end);
 
- 		}
 
- 		public StateMachineScope (Instruction start, Instruction end)
 
- 		{
 
- 			this.start = new InstructionOffset (start);
 
- 			this.end = end != null ? new InstructionOffset (end) : new InstructionOffset ();
 
- 		}
 
- 	}
 
- 	public sealed class StateMachineScopeDebugInformation : CustomDebugInformation {
 
- 		internal Collection<StateMachineScope> scopes;
 
- 		public Collection<StateMachineScope> Scopes {
 
- 			get { return scopes ?? (scopes = new Collection<StateMachineScope> ()); }
 
- 		}
 
- 		public override CustomDebugInformationKind Kind {
 
- 			get { return CustomDebugInformationKind.StateMachineScope; }
 
- 		}
 
- 		public static Guid KindIdentifier = new Guid ("{6DA9A61E-F8C7-4874-BE62-68BC5630DF71}");
 
- 		public StateMachineScopeDebugInformation ()
 
- 			: base (KindIdentifier)
 
- 		{
 
- 		}
 
- 	}
 
- 	public sealed class EmbeddedSourceDebugInformation : CustomDebugInformation {
 
- 		internal byte [] content;
 
- 		internal bool compress;
 
- 		public byte [] Content {
 
- 			get { return content; }
 
- 			set { content = value; }
 
- 		}
 
- 		public bool Compress {
 
- 			get { return compress; }
 
- 			set { compress = value; }
 
- 		}
 
- 		public override CustomDebugInformationKind Kind {
 
- 			get { return CustomDebugInformationKind.EmbeddedSource; }
 
- 		}
 
- 		public static Guid KindIdentifier = new Guid ("{0E8A571B-6926-466E-B4AD-8AB04611F5FE}");
 
- 		public EmbeddedSourceDebugInformation (byte [] content, bool compress)
 
- 			: base (KindIdentifier)
 
- 		{
 
- 			this.content = content;
 
- 			this.compress = compress;
 
- 		}
 
- 	}
 
- 	public sealed class SourceLinkDebugInformation : CustomDebugInformation {
 
- 		internal string content;
 
- 		public string Content {
 
- 			get { return content; }
 
- 			set { content = value; }
 
- 		}
 
- 		public override CustomDebugInformationKind Kind {
 
- 			get { return CustomDebugInformationKind.SourceLink; }
 
- 		}
 
- 		public static Guid KindIdentifier = new Guid ("{CC110556-A091-4D38-9FEC-25AB9A351A6A}");
 
- 		public SourceLinkDebugInformation (string content)
 
- 			: base (KindIdentifier)
 
- 		{
 
- 			this.content = content;
 
- 		}
 
- 	}
 
- 	public sealed class MethodDebugInformation : DebugInformation {
 
- 		internal MethodDefinition method;
 
- 		internal Collection<SequencePoint> sequence_points;
 
- 		internal ScopeDebugInformation scope;
 
- 		internal MethodDefinition kickoff_method;
 
- 		internal int code_size;
 
- 		internal MetadataToken local_var_token;
 
- 		public MethodDefinition Method {
 
- 			get { return method; }
 
- 		}
 
- 		public bool HasSequencePoints {
 
- 			get { return !sequence_points.IsNullOrEmpty (); }
 
- 		}
 
- 		public Collection<SequencePoint> SequencePoints {
 
- 			get {
 
- 				if (sequence_points == null)
 
- 					Interlocked.CompareExchange (ref sequence_points, new Collection<SequencePoint> (), null);
 
- 				return sequence_points;
 
- 			}
 
- 		}
 
- 		public ScopeDebugInformation Scope {
 
- 			get { return scope; }
 
- 			set { scope = value; }
 
- 		}
 
- 		public MethodDefinition StateMachineKickOffMethod {
 
- 			get { return kickoff_method; }
 
- 			set { kickoff_method = value; }
 
- 		}
 
- 		internal MethodDebugInformation (MethodDefinition method)
 
- 		{
 
- 			if (method == null)
 
- 				throw new ArgumentNullException ("method");
 
- 			this.method = method;
 
- 			this.token = new MetadataToken (TokenType.MethodDebugInformation, method.MetadataToken.RID);
 
- 		}
 
- 		public SequencePoint GetSequencePoint (Instruction instruction)
 
- 		{
 
- 			if (!HasSequencePoints)
 
- 				return null;
 
- 			for (int i = 0; i < sequence_points.Count; i++)
 
- 				if (sequence_points [i].Offset == instruction.Offset)
 
- 					return sequence_points [i];
 
- 			return null;
 
- 		}
 
- 		public IDictionary<Instruction, SequencePoint> GetSequencePointMapping ()
 
- 		{
 
- 			var instruction_mapping = new Dictionary<Instruction, SequencePoint> ();
 
- 			if (!HasSequencePoints || !method.HasBody)
 
- 				return instruction_mapping;
 
- 			var offset_mapping = new Dictionary<int, SequencePoint> (sequence_points.Count);
 
- 			for (int i = 0; i < sequence_points.Count; i++) {
 
- 				if (!offset_mapping.ContainsKey (sequence_points [i].Offset))
 
- 					offset_mapping.Add (sequence_points [i].Offset, sequence_points [i]);
 
- 			}
 
- 			var instructions = method.Body.Instructions;
 
- 			for (int i = 0; i < instructions.Count; i++) {
 
- 				SequencePoint sequence_point;
 
- 				if (offset_mapping.TryGetValue (instructions [i].Offset, out sequence_point))
 
- 					instruction_mapping.Add (instructions [i], sequence_point);
 
- 			}
 
- 			return instruction_mapping;
 
- 		}
 
- 		public IEnumerable<ScopeDebugInformation> GetScopes ()
 
- 		{
 
- 			if (scope == null)
 
- 				return Empty<ScopeDebugInformation>.Array;
 
- 			return GetScopes (new[] { scope });
 
- 		}
 
- 		static IEnumerable<ScopeDebugInformation> GetScopes (IList<ScopeDebugInformation> scopes)
 
- 		{
 
- 			for (int i = 0; i < scopes.Count; i++) {
 
- 				var scope = scopes [i];
 
- 				yield return scope;
 
- 				if (!scope.HasScopes)
 
- 					continue;
 
- 				foreach (var sub_scope in GetScopes (scope.Scopes))
 
- 					yield return sub_scope;
 
- 			}
 
- 		}
 
- 		public bool TryGetName (VariableDefinition variable, out string name)
 
- 		{
 
- 			name = null;
 
- 			var has_name = false;
 
- 			var unique_name = "";
 
- 			foreach (var scope in GetScopes ()) {
 
- 				string slot_name;
 
- 				if (!scope.TryGetName (variable, out slot_name))
 
- 					continue;
 
- 				if (!has_name) {
 
- 					has_name = true;
 
- 					unique_name = slot_name;
 
- 					continue;
 
- 				}
 
- 				if (unique_name != slot_name)
 
- 					return false;
 
- 			}
 
- 			name = unique_name;
 
- 			return has_name;
 
- 		}
 
- 	}
 
- 	public interface ISymbolReader : IDisposable {
 
- 		ISymbolWriterProvider GetWriterProvider ();
 
- 		bool ProcessDebugHeader (ImageDebugHeader header);
 
- 		MethodDebugInformation Read (MethodDefinition method);
 
- 	}
 
- 	public interface ISymbolReaderProvider {
 
- 		ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName);
 
- 		ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream);
 
- 	}
 
- #if !NET_CORE
 
- 	[Serializable]
 
- #endif
 
- 	public sealed class SymbolsNotFoundException : FileNotFoundException {
 
- 		public SymbolsNotFoundException (string message) : base (message)
 
- 		{
 
- 		}
 
- #if !NET_CORE
 
- 		SymbolsNotFoundException (
 
- 			System.Runtime.Serialization.SerializationInfo info,
 
- 			System.Runtime.Serialization.StreamingContext context)
 
- 			: base (info, context)
 
- 		{
 
- 		}
 
- #endif
 
- 	}
 
- #if !NET_CORE
 
- 	[Serializable]
 
- #endif
 
- 	public sealed class SymbolsNotMatchingException : InvalidOperationException {
 
- 		public SymbolsNotMatchingException (string message) : base (message)
 
- 		{
 
- 		}
 
- #if !NET_CORE
 
- 		SymbolsNotMatchingException (
 
- 			System.Runtime.Serialization.SerializationInfo info,
 
- 			System.Runtime.Serialization.StreamingContext context)
 
- 			: base (info, context)
 
- 		{
 
- 		}
 
- #endif
 
- 	}
 
- 	public class DefaultSymbolReaderProvider : ISymbolReaderProvider {
 
- 		readonly bool throw_if_no_symbol;
 
- 		public DefaultSymbolReaderProvider ()
 
- 			: this (throwIfNoSymbol: true)
 
- 		{
 
- 		}
 
- 		public DefaultSymbolReaderProvider (bool throwIfNoSymbol)
 
- 		{
 
- 			throw_if_no_symbol = throwIfNoSymbol;
 
- 		}
 
- 		public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
 
- 		{
 
- 			if (module.Image.HasDebugTables ())
 
- 				return null;
 
- 			if (module.HasDebugHeader) {
 
- 				var header = module.GetDebugHeader ();
 
- 				var entry = header.GetEmbeddedPortablePdbEntry ();
 
- 				if (entry != null)
 
- 					return new EmbeddedPortablePdbReaderProvider ().GetSymbolReader (module, fileName);
 
- 			}
 
- 			var pdb_file_name = Mixin.GetPdbFileName (fileName);
 
- 			if (File.Exists (pdb_file_name)) {
 
- 				if (Mixin.IsPortablePdb (Mixin.GetPdbFileName (fileName)))
 
- 					return new PortablePdbReaderProvider ().GetSymbolReader (module, fileName);
 
- 				try {
 
- 					return SymbolProvider.GetReaderProvider (SymbolKind.NativePdb).GetSymbolReader (module, fileName);
 
- 				} catch (Exception) {
 
- 					// We might not include support for native pdbs.
 
- 				}
 
- 			}
 
- 			var mdb_file_name = Mixin.GetMdbFileName (fileName);
 
- 			if (File.Exists (mdb_file_name)) {
 
- 				try {
 
- 					return SymbolProvider.GetReaderProvider (SymbolKind.Mdb).GetSymbolReader (module, fileName);
 
- 				} catch (Exception) {
 
- 					// We might not include support for mdbs.
 
- 				}
 
- 			}
 
- 			if (throw_if_no_symbol)
 
- 				throw new SymbolsNotFoundException (string.Format ("No symbol found for file: {0}", fileName));
 
- 			return null;
 
- 		}
 
- 		public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
 
- 		{
 
- 			if (module.Image.HasDebugTables ())
 
- 				return null;
 
- 			if (module.HasDebugHeader) {
 
- 				var header = module.GetDebugHeader ();
 
- 				var entry = header.GetEmbeddedPortablePdbEntry ();
 
- 				if (entry != null)
 
- 					return new EmbeddedPortablePdbReaderProvider ().GetSymbolReader (module, "");
 
- 			}
 
- 			Mixin.CheckStream (symbolStream);
 
- 			Mixin.CheckReadSeek (symbolStream);
 
- 			var position = symbolStream.Position;
 
- 			const int portablePdbHeader = 0x424a5342;
 
- 			var reader = new BinaryStreamReader (symbolStream);
 
- 			var intHeader = reader.ReadInt32 ();
 
- 			symbolStream.Position = position;
 
- 			if (intHeader == portablePdbHeader) {
 
- 				return new PortablePdbReaderProvider ().GetSymbolReader (module, symbolStream);
 
- 			}
 
- 			const string nativePdbHeader = "Microsoft C/C++ MSF 7.00";
 
- 			var bytesHeader = reader.ReadBytes (nativePdbHeader.Length);
 
- 			symbolStream.Position = position;
 
- 			var isNativePdb = true;
 
- 			for (var i = 0; i < bytesHeader.Length; i++) {
 
- 				if (bytesHeader [i] != (byte) nativePdbHeader [i]) {
 
- 					isNativePdb = false;
 
- 					break;
 
- 				}
 
- 			}
 
- 			if (isNativePdb) {
 
- 				try {
 
- 					return SymbolProvider.GetReaderProvider (SymbolKind.NativePdb).GetSymbolReader (module, symbolStream);
 
- 				} catch (Exception) {
 
- 					// We might not include support for native pdbs.
 
- 				}
 
- 			}
 
- 			const long mdbHeader = 0x45e82623fd7fa614;
 
- 			var longHeader = reader.ReadInt64 ();
 
- 			symbolStream.Position = position;
 
- 			if (longHeader == mdbHeader) {
 
- 				try {
 
- 					return SymbolProvider.GetReaderProvider (SymbolKind.Mdb).GetSymbolReader (module, symbolStream);
 
- 				} catch (Exception) {
 
- 					// We might not include support for mdbs.
 
- 				}
 
- 			}
 
- 			if (throw_if_no_symbol)
 
- 				throw new SymbolsNotFoundException (string.Format ("No symbols found in stream"));
 
- 			return null;
 
- 		}
 
- 	}
 
- 	enum SymbolKind {
 
- 		NativePdb,
 
- 		PortablePdb,
 
- 		EmbeddedPortablePdb,
 
- 		Mdb,
 
- 	}
 
- 	static class SymbolProvider {
 
- 		static SR.AssemblyName GetSymbolAssemblyName (SymbolKind kind)
 
- 		{
 
- 			if (kind == SymbolKind.PortablePdb)
 
- 				throw new ArgumentException ();
 
- 			var suffix = GetSymbolNamespace (kind);
 
- 			var cecil_name = typeof(SymbolProvider).Assembly.GetName();
 
- 			var name = new SR.AssemblyName
 
- 			{
 
- 				Name = cecil_name.Name + "." + suffix,
 
- 				Version = cecil_name.Version,
 
- #if NET_CORE
 
- 				CultureName = cecil_name.CultureName,
 
- #else
 
- 				CultureInfo = cecil_name.CultureInfo,
 
- #endif
 
- 			};
 
- 			name.SetPublicKeyToken (cecil_name.GetPublicKeyToken ());
 
- 			return name;
 
- 		}
 
- 		static Type GetSymbolType (SymbolKind kind, string fullname)
 
- 		{
 
- 			var type = Type.GetType (fullname);
 
- 			if (type != null)
 
- 				return type;
 
- 			var assembly_name = GetSymbolAssemblyName (kind);
 
- 			type = Type.GetType (fullname + ", " + assembly_name.FullName);
 
- 			if (type != null)
 
- 				return type;
 
- 			try {
 
- 				var assembly = SR.Assembly.Load (assembly_name);
 
- 				if (assembly != null)
 
- 					return assembly.GetType (fullname);
 
- 			} catch (FileNotFoundException) {
 
- 			} catch (FileLoadException) {
 
- 			}
 
- 			return null;
 
- 		}
 
- 		public static ISymbolReaderProvider GetReaderProvider (SymbolKind kind)
 
- 		{
 
- 			if (kind == SymbolKind.PortablePdb)
 
- 				return new PortablePdbReaderProvider ();
 
- 			if (kind == SymbolKind.EmbeddedPortablePdb)
 
- 				return new EmbeddedPortablePdbReaderProvider ();
 
- 			var provider_name = GetSymbolTypeName (kind, "ReaderProvider");
 
- 			var type = GetSymbolType (kind, provider_name);
 
- 			if (type == null)
 
- 				throw new TypeLoadException ("Could not find symbol provider type " + provider_name);
 
- 			return (ISymbolReaderProvider) Activator.CreateInstance (type);
 
- 		}
 
- 		static string GetSymbolTypeName (SymbolKind kind, string name)
 
- 		{
 
- 			return "Mono.Cecil" + "." + GetSymbolNamespace (kind) + "." + kind + name;
 
- 		}
 
- 		static string GetSymbolNamespace (SymbolKind kind)
 
- 		{
 
- 			if (kind == SymbolKind.PortablePdb || kind == SymbolKind.EmbeddedPortablePdb)
 
- 				return "Cil";
 
- 			if (kind == SymbolKind.NativePdb)
 
- 				return "Pdb";
 
- 			if (kind == SymbolKind.Mdb)
 
- 				return "Mdb";
 
- 			throw new ArgumentException ();
 
- 		}
 
- 	}
 
- 	public interface ISymbolWriter : IDisposable {
 
- 		ISymbolReaderProvider GetReaderProvider ();
 
- 		ImageDebugHeader GetDebugHeader ();
 
- 		void Write (MethodDebugInformation info);
 
- 	}
 
- 	public interface ISymbolWriterProvider {
 
- 		ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName);
 
- 		ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream);
 
- 	}
 
- 	public class DefaultSymbolWriterProvider : ISymbolWriterProvider {
 
- 		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
 
- 		{
 
- 			var reader = module.SymbolReader;
 
- 			if (reader == null)
 
- 				throw new InvalidOperationException ();
 
- 			if (module.Image != null && module.Image.HasDebugTables ())
 
- 				return null;
 
- 			return reader.GetWriterProvider ().GetSymbolWriter (module, fileName);
 
- 		}
 
- 		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
 
- 		{
 
- 			throw new NotSupportedException ();
 
- 		}
 
- 	}
 
- }
 
- namespace ILRuntime.Mono.Cecil {
 
- 	static partial class Mixin {
 
- 		public static ImageDebugHeaderEntry GetCodeViewEntry (this ImageDebugHeader header)
 
- 		{
 
- 			return GetEntry (header, ImageDebugType.CodeView);
 
- 		}
 
- 		public static ImageDebugHeaderEntry GetDeterministicEntry (this ImageDebugHeader header)
 
- 		{
 
- 			return GetEntry (header, ImageDebugType.Deterministic);
 
- 		}
 
- 		public static ImageDebugHeader AddDeterministicEntry (this ImageDebugHeader header)
 
- 		{
 
- 			var entry = new ImageDebugHeaderEntry (new ImageDebugDirectory { Type = ImageDebugType.Deterministic }, Empty<byte>.Array);
 
- 			if (header == null)
 
- 				return new ImageDebugHeader (entry);
 
- 			var entries = new ImageDebugHeaderEntry [header.Entries.Length + 1];
 
- 			Array.Copy (header.Entries, entries, header.Entries.Length);
 
- 			entries [entries.Length - 1] = entry;
 
- 			return new ImageDebugHeader (entries);
 
- 		}
 
- 		public static ImageDebugHeaderEntry GetEmbeddedPortablePdbEntry (this ImageDebugHeader header)
 
- 		{
 
- 			return GetEntry (header, ImageDebugType.EmbeddedPortablePdb);
 
- 		}
 
- 		private static ImageDebugHeaderEntry GetEntry (this ImageDebugHeader header, ImageDebugType type)
 
- 		{
 
- 			if (!header.HasEntries)
 
- 				return null;
 
- 			for (var i = 0; i < header.Entries.Length; i++) {
 
- 				var entry = header.Entries [i];
 
- 				if (entry.Directory.Type == type)
 
- 					return entry;
 
- 			}
 
- 			return null;
 
- 		}
 
- 		public static string GetPdbFileName (string assemblyFileName)
 
- 		{
 
- 			return Path.ChangeExtension (assemblyFileName, ".pdb");
 
- 		}
 
- 		public static string GetMdbFileName (string assemblyFileName)
 
- 		{
 
- 			return assemblyFileName + ".mdb";
 
- 		}
 
- 		public static bool IsPortablePdb (string fileName)
 
- 		{
 
- 			using (var file = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
 
- 				return IsPortablePdb (file);
 
- 		}
 
- 		public static bool IsPortablePdb (Stream stream)
 
- 		{
 
- 			const uint ppdb_signature = 0x424a5342;
 
- 			if (stream.Length < 4) return false;
 
- 			var position = stream.Position;
 
- 			try {
 
- 				var reader = new BinaryReader (stream);
 
- 				return reader.ReadUInt32 () == ppdb_signature;
 
- 			} finally {
 
- 				stream.Position = position;
 
- 			}
 
- 		}
 
- 	}
 
- }
 
 
  |