| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582 | 
							- //
 
- // 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.IO.Compression;
 
- using ILRuntime.Mono.Cecil.Metadata;
 
- using ILRuntime.Mono.Cecil.PE;
 
- namespace ILRuntime.Mono.Cecil.Cil {
 
- 	public sealed class PortablePdbReaderProvider : ISymbolReaderProvider {
 
- 		public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
 
- 		{
 
- 			Mixin.CheckModule (module);
 
- 			Mixin.CheckFileName (fileName);
 
- 			var file = File.OpenRead (Mixin.GetPdbFileName (fileName));
 
- 			return GetSymbolReader (module, Disposable.Owned (file as Stream), file.Name);
 
- 		}
 
- 		public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
 
- 		{
 
- 			Mixin.CheckModule (module);
 
- 			Mixin.CheckStream (symbolStream);
 
- 			return GetSymbolReader (module, Disposable.NotOwned (symbolStream), symbolStream.GetFileName ());
 
- 		}
 
- 		ISymbolReader GetSymbolReader (ModuleDefinition module, Disposable<Stream> symbolStream, string fileName)
 
- 		{
 
- 			return new PortablePdbReader (ImageReader.ReadPortablePdb (symbolStream, fileName), module);
 
- 		}
 
- 	}
 
- 	public sealed class PortablePdbReader : ISymbolReader {
 
- 		readonly Image image;
 
- 		readonly ModuleDefinition module;
 
- 		readonly MetadataReader reader;
 
- 		readonly MetadataReader debug_reader;
 
- 		bool IsEmbedded { get { return reader.image == debug_reader.image; } }
 
- 		internal PortablePdbReader (Image image, ModuleDefinition module)
 
- 		{
 
- 			this.image = image;
 
- 			this.module = module;
 
- 			this.reader = module.reader;
 
- 			this.debug_reader = new MetadataReader (image, module, this.reader);
 
- 		}
 
- 		public ISymbolWriterProvider GetWriterProvider ()
 
- 		{
 
- 			return new PortablePdbWriterProvider ();
 
- 		}
 
- 		public bool ProcessDebugHeader (ImageDebugHeader header)
 
- 		{
 
- 			if (image == module.Image)
 
- 				return true;
 
- 			var entry = header.GetCodeViewEntry ();
 
- 			if (entry == null)
 
- 				return false;
 
- 			var data = entry.Data;
 
- 			if (data.Length < 24)
 
- 				return false;
 
- 			var magic = ReadInt32 (data, 0);
 
- 			if (magic != 0x53445352)
 
- 				return false;
 
- 			var buffer = new byte [16];
 
- 			Buffer.BlockCopy (data, 4, buffer, 0, 16);
 
- 			var module_guid = new Guid (buffer);
 
- 			Buffer.BlockCopy (image.PdbHeap.Id, 0, buffer, 0, 16);
 
- 			var pdb_guid = new Guid (buffer);
 
- 			if (module_guid != pdb_guid)
 
- 				return false;
 
- 			ReadModule ();
 
- 			return true;
 
- 		}
 
- 		static int ReadInt32 (byte [] bytes, int start)
 
- 		{
 
- 			return (bytes [start]
 
- 				| (bytes [start + 1] << 8)
 
- 				| (bytes [start + 2] << 16)
 
- 				| (bytes [start + 3] << 24));
 
- 		}
 
- 		void ReadModule ()
 
- 		{
 
- 			module.custom_infos = debug_reader.GetCustomDebugInformation (module);
 
- 		}
 
- 		public MethodDebugInformation Read (MethodDefinition method)
 
- 		{
 
- 			var info = new MethodDebugInformation (method);
 
- 			ReadSequencePoints (info);
 
- 			ReadScope (info);
 
- 			ReadStateMachineKickOffMethod (info);
 
- 			ReadCustomDebugInformations (info);
 
- 			return info;
 
- 		}
 
- 		void ReadSequencePoints (MethodDebugInformation method_info)
 
- 		{
 
- 			method_info.sequence_points = debug_reader.ReadSequencePoints (method_info.method);
 
- 		}
 
- 		void ReadScope (MethodDebugInformation method_info)
 
- 		{
 
- 			method_info.scope = debug_reader.ReadScope (method_info.method);
 
- 		}
 
- 		void ReadStateMachineKickOffMethod (MethodDebugInformation method_info)
 
- 		{
 
- 			method_info.kickoff_method = debug_reader.ReadStateMachineKickoffMethod (method_info.method);
 
- 		}
 
- 		void ReadCustomDebugInformations (MethodDebugInformation info)
 
- 		{
 
- 			info.method.custom_infos = debug_reader.GetCustomDebugInformation (info.method);
 
- 		}
 
- 		public void Dispose ()
 
- 		{
 
- 			if (IsEmbedded)
 
- 				return;
 
- 			image.Dispose ();
 
- 		}
 
- 	}
 
- 	public sealed class EmbeddedPortablePdbReaderProvider : ISymbolReaderProvider {
 
- 		public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
 
- 		{
 
- 			Mixin.CheckModule (module);
 
- 			var header = module.GetDebugHeader ();
 
- 			var entry = header.GetEmbeddedPortablePdbEntry ();
 
- 			if (entry == null)
 
- 				throw new InvalidOperationException ();
 
- 			return new EmbeddedPortablePdbReader (
 
- 				(PortablePdbReader) new PortablePdbReaderProvider ().GetSymbolReader (module, GetPortablePdbStream (entry)));
 
- 		}
 
- 		static Stream GetPortablePdbStream (ImageDebugHeaderEntry entry)
 
- 		{
 
- 			var compressed_stream = new MemoryStream (entry.Data);
 
- 			var reader = new BinaryStreamReader (compressed_stream);
 
- 			reader.ReadInt32 (); // signature
 
- 			var length = reader.ReadInt32 ();
 
- 			var decompressed_stream = new MemoryStream (length);
 
- 			using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true))
 
- 				deflate_stream.CopyTo (decompressed_stream);
 
- 			return decompressed_stream;
 
- 		}
 
- 		public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
 
- 		{
 
- 			throw new NotSupportedException ();
 
- 		}
 
- 	}
 
- 	public sealed class EmbeddedPortablePdbReader : ISymbolReader
 
- 	{
 
- 		private readonly PortablePdbReader reader;
 
- 		internal EmbeddedPortablePdbReader (PortablePdbReader reader)
 
- 		{
 
- 			if (reader == null)
 
- 				throw new ArgumentNullException ();
 
- 			this.reader = reader;
 
- 		}
 
- 		public ISymbolWriterProvider GetWriterProvider ()
 
- 		{
 
- 			return new EmbeddedPortablePdbWriterProvider ();
 
- 		}
 
- 		public bool ProcessDebugHeader (ImageDebugHeader header)
 
- 		{
 
- 			return reader.ProcessDebugHeader (header);
 
- 		}
 
- 		public MethodDebugInformation Read (MethodDefinition method)
 
- 		{
 
- 			return reader.Read (method);
 
- 		}
 
- 		public void Dispose ()
 
- 		{
 
- 			reader.Dispose ();
 
- 		}
 
- 	}
 
- 	public sealed class PortablePdbWriterProvider : ISymbolWriterProvider
 
- 	{
 
- 		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
 
- 		{
 
- 			Mixin.CheckModule (module);
 
- 			Mixin.CheckFileName (fileName);
 
- 			var file = File.OpenWrite (Mixin.GetPdbFileName (fileName));
 
- 			return GetSymbolWriter (module, Disposable.Owned (file as Stream));
 
- 		}
 
- 		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
 
- 		{
 
- 			Mixin.CheckModule (module);
 
- 			Mixin.CheckStream (symbolStream);
 
- 			return GetSymbolWriter (module, Disposable.NotOwned (symbolStream));
 
- 		}
 
- 		ISymbolWriter GetSymbolWriter (ModuleDefinition module, Disposable<Stream> stream)
 
- 		{
 
- 			var metadata = new MetadataBuilder (module, this);
 
- 			var writer = ImageWriter.CreateDebugWriter (module, metadata, stream);
 
- 			return new PortablePdbWriter (metadata, module, writer);
 
- 		}
 
- 	}
 
- 	public sealed class PortablePdbWriter : ISymbolWriter {
 
- 		readonly MetadataBuilder pdb_metadata;
 
- 		readonly ModuleDefinition module;
 
- 		readonly ImageWriter writer;
 
- 		MetadataBuilder module_metadata;
 
- 		bool IsEmbedded { get { return writer == null; } }
 
- 		internal PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module)
 
- 		{
 
- 			this.pdb_metadata = pdb_metadata;
 
- 			this.module = module;
 
- 			this.module_metadata = module.metadata_builder;
 
- 			if (module_metadata != pdb_metadata)
 
- 				this.pdb_metadata.metadata_builder = this.module_metadata;
 
- 			pdb_metadata.AddCustomDebugInformations (module);
 
- 		}
 
- 		internal PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module, ImageWriter writer)
 
- 			: this (pdb_metadata, module)
 
- 		{
 
- 			this.writer = writer;
 
- 		}
 
- 		public ISymbolReaderProvider GetReaderProvider ()
 
- 		{
 
- 			return new PortablePdbReaderProvider ();
 
- 		}
 
- 		public ImageDebugHeader GetDebugHeader ()
 
- 		{
 
- 			if (IsEmbedded)
 
- 				return new ImageDebugHeader ();
 
- 			var directory = new ImageDebugDirectory () {
 
- 				MajorVersion = 256,
 
- 				MinorVersion = 20557,
 
- 				Type = ImageDebugType.CodeView,
 
- 				TimeDateStamp = (int) module.timestamp,
 
- 			};
 
- 			var buffer = new ByteBuffer ();
 
- 			// RSDS
 
- 			buffer.WriteUInt32 (0x53445352);
 
- 			// Module ID
 
- 			buffer.WriteBytes (module.Mvid.ToByteArray ());
 
- 			// PDB Age
 
- 			buffer.WriteUInt32 (1);
 
- 			// PDB Path
 
- 			buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes (writer.BaseStream.GetFileName ()));
 
- 			buffer.WriteByte (0);
 
- 			var data = new byte [buffer.length];
 
- 			Buffer.BlockCopy (buffer.buffer, 0, data, 0, buffer.length);
 
- 			directory.SizeOfData = data.Length;
 
- 			return new ImageDebugHeader (new ImageDebugHeaderEntry (directory, data));
 
- 		}
 
- 		public void Write (MethodDebugInformation info)
 
- 		{
 
- 			CheckMethodDebugInformationTable ();
 
- 			pdb_metadata.AddMethodDebugInformation (info);
 
- 		}
 
- 		void CheckMethodDebugInformationTable ()
 
- 		{
 
- 			var mdi = pdb_metadata.table_heap.GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation);
 
- 			if (mdi.length > 0)
 
- 				return;
 
- 			// The MethodDebugInformation table has the same length as the Method table
 
- 			mdi.rows = new Row<uint, uint> [module_metadata.method_rid - 1];
 
- 			mdi.length = mdi.rows.Length;
 
- 		}
 
- 		public void Dispose ()
 
- 		{
 
- 			if (IsEmbedded)
 
- 				return;
 
- 			WritePdbFile ();
 
- 		}
 
- 		void WritePdbFile ()
 
- 		{
 
- 			WritePdbHeap ();
 
- 			WriteTableHeap ();
 
- 			writer.BuildMetadataTextMap ();
 
- 			writer.WriteMetadataHeader ();
 
- 			writer.WriteMetadata ();
 
- 			writer.Flush ();
 
- 			writer.stream.Dispose ();
 
- 		}
 
- 		void WritePdbHeap ()
 
- 		{
 
- 			var pdb_heap = pdb_metadata.pdb_heap;
 
- 			pdb_heap.WriteBytes (module.Mvid.ToByteArray ());
 
- 			pdb_heap.WriteUInt32 (module_metadata.timestamp);
 
- 			pdb_heap.WriteUInt32 (module_metadata.entry_point.ToUInt32 ());
 
- 			var table_heap = module_metadata.table_heap;
 
- 			var tables = table_heap.tables;
 
- 			ulong valid = 0;
 
- 			for (int i = 0; i < tables.Length; i++) {
 
- 				if (tables [i] == null || tables [i].Length == 0)
 
- 					continue;
 
- 				valid |= (1UL << i);
 
- 			}
 
- 			pdb_heap.WriteUInt64 (valid);
 
- 			for (int i = 0; i < tables.Length; i++) {
 
- 				if (tables [i] == null || tables [i].Length == 0)
 
- 					continue;
 
- 				pdb_heap.WriteUInt32 ((uint) tables [i].Length);
 
- 			}
 
- 		}
 
- 		void WriteTableHeap ()
 
- 		{
 
- 			pdb_metadata.table_heap.string_offsets = pdb_metadata.string_heap.WriteStrings ();
 
- 			pdb_metadata.table_heap.ComputeTableInformations ();
 
- 			pdb_metadata.table_heap.WriteTableHeap ();
 
- 		}
 
- 	}
 
- 	public sealed class EmbeddedPortablePdbWriterProvider : ISymbolWriterProvider {
 
- 		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName)
 
- 		{
 
- 			Mixin.CheckModule (module);
 
- 			Mixin.CheckFileName (fileName);
 
- 			var stream = new MemoryStream ();
 
- 			var pdb_writer = (PortablePdbWriter) new PortablePdbWriterProvider ().GetSymbolWriter (module, stream);
 
- 			return new EmbeddedPortablePdbWriter (stream, pdb_writer);
 
- 		}
 
- 		public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream)
 
- 		{
 
- 			throw new NotSupportedException ();
 
- 		}
 
- 	}
 
- 	public sealed class EmbeddedPortablePdbWriter : ISymbolWriter {
 
- 		readonly Stream stream;
 
- 		readonly PortablePdbWriter writer;
 
- 		internal EmbeddedPortablePdbWriter (Stream stream, PortablePdbWriter writer)
 
- 		{
 
- 			this.stream = stream;
 
- 			this.writer = writer;
 
- 		}
 
- 		public ISymbolReaderProvider GetReaderProvider ()
 
- 		{
 
- 			return new EmbeddedPortablePdbReaderProvider ();
 
- 		}
 
- 		public ImageDebugHeader GetDebugHeader ()
 
- 		{
 
- 			writer.Dispose ();
 
- 			var directory = new ImageDebugDirectory {
 
- 				Type = ImageDebugType.EmbeddedPortablePdb,
 
- 				MajorVersion = 0x0100,
 
- 				MinorVersion = 0x0100,
 
- 			};
 
- 			var data = new MemoryStream ();
 
- 			var w = new BinaryStreamWriter (data);
 
- 			w.WriteByte (0x4d);
 
- 			w.WriteByte (0x50);
 
- 			w.WriteByte (0x44);
 
- 			w.WriteByte (0x42);
 
- 			w.WriteInt32 ((int) stream.Length);
 
- 			stream.Position = 0;
 
- 			using (var compress_stream = new DeflateStream (data, CompressionMode.Compress, leaveOpen: true))
 
- 				stream.CopyTo (compress_stream);
 
- 			directory.SizeOfData = (int) data.Length;
 
- 			return new ImageDebugHeader (new [] {
 
- 				writer.GetDebugHeader ().Entries [0],
 
- 				new ImageDebugHeaderEntry (directory, data.ToArray ())
 
- 			});
 
- 		}
 
- 		public void Write (MethodDebugInformation info)
 
- 		{
 
- 			writer.Write (info);
 
- 		}
 
- 		public void Dispose ()
 
- 		{
 
- 		}
 
- 	}
 
- 	static class PdbGuidMapping {
 
- 		static readonly Dictionary<Guid, DocumentLanguage> guid_language = new Dictionary<Guid, DocumentLanguage> ();
 
- 		static readonly Dictionary<DocumentLanguage, Guid> language_guid = new Dictionary<DocumentLanguage, Guid> ();
 
- 		static PdbGuidMapping ()
 
- 		{
 
- 			AddMapping (DocumentLanguage.C, new Guid ("63a08714-fc37-11d2-904c-00c04fa302a1"));
 
- 			AddMapping (DocumentLanguage.Cpp, new Guid ("3a12d0b7-c26c-11d0-b442-00a0244a1dd2"));
 
- 			AddMapping (DocumentLanguage.CSharp, new Guid ("3f5162f8-07c6-11d3-9053-00c04fa302a1"));
 
- 			AddMapping (DocumentLanguage.Basic, new Guid ("3a12d0b8-c26c-11d0-b442-00a0244a1dd2"));
 
- 			AddMapping (DocumentLanguage.Java, new Guid ("3a12d0b4-c26c-11d0-b442-00a0244a1dd2"));
 
- 			AddMapping (DocumentLanguage.Cobol, new Guid ("af046cd1-d0e1-11d2-977c-00a0c9b4d50c"));
 
- 			AddMapping (DocumentLanguage.Pascal, new Guid ("af046cd2-d0e1-11d2-977c-00a0c9b4d50c"));
 
- 			AddMapping (DocumentLanguage.Cil, new Guid ("af046cd3-d0e1-11d2-977c-00a0c9b4d50c"));
 
- 			AddMapping (DocumentLanguage.JScript, new Guid ("3a12d0b6-c26c-11d0-b442-00a0244a1dd2"));
 
- 			AddMapping (DocumentLanguage.Smc, new Guid ("0d9b9f7b-6611-11d3-bd2a-0000f80849bd"));
 
- 			AddMapping (DocumentLanguage.MCpp, new Guid ("4b35fde8-07c6-11d3-9053-00c04fa302a1"));
 
- 			AddMapping (DocumentLanguage.FSharp, new Guid ("ab4f38c9-b6e6-43ba-be3b-58080b2ccce3"));
 
- 		}
 
- 		static void AddMapping (DocumentLanguage language, Guid guid)
 
- 		{
 
- 			guid_language.Add (guid, language);
 
- 			language_guid.Add (language, guid);
 
- 		}
 
- 		static readonly Guid type_text = new Guid ("5a869d0b-6611-11d3-bd2a-0000f80849bd");
 
- 		public static DocumentType ToType (this Guid guid)
 
- 		{
 
- 			if (guid == type_text)
 
- 				return DocumentType.Text;
 
- 			return DocumentType.Other;
 
- 		}
 
- 		public static Guid ToGuid (this DocumentType type)
 
- 		{
 
- 			if (type == DocumentType.Text)
 
- 				return type_text;
 
- 			return new Guid ();
 
- 		}
 
- 		static readonly Guid hash_md5 = new Guid ("406ea660-64cf-4c82-b6f0-42d48172a799");
 
- 		static readonly Guid hash_sha1 = new Guid ("ff1816ec-aa5e-4d10-87f7-6f4963833460");
 
- 		static readonly Guid hash_sha256 = new Guid ("8829d00f-11b8-4213-878b-770e8597ac16");
 
- 		public static DocumentHashAlgorithm ToHashAlgorithm (this Guid guid)
 
- 		{
 
- 			if (guid == hash_md5)
 
- 				return DocumentHashAlgorithm.MD5;
 
- 			if (guid == hash_sha1)
 
- 				return DocumentHashAlgorithm.SHA1;
 
- 			if (guid == hash_sha256)
 
- 				return DocumentHashAlgorithm.SHA256;
 
- 			return DocumentHashAlgorithm.None;
 
- 		}
 
- 		public static Guid ToGuid (this DocumentHashAlgorithm hash_algo)
 
- 		{
 
- 			if (hash_algo == DocumentHashAlgorithm.MD5)
 
- 				return hash_md5;
 
- 			if (hash_algo == DocumentHashAlgorithm.SHA1)
 
- 				return hash_sha1;
 
- 			if (hash_algo == DocumentHashAlgorithm.SHA256)
 
- 				return hash_sha256;
 
- 			return new Guid ();
 
- 		}
 
- 		public static DocumentLanguage ToLanguage (this Guid guid)
 
- 		{
 
- 			DocumentLanguage language;
 
- 			if (!guid_language.TryGetValue (guid, out language))
 
- 				return DocumentLanguage.Other;
 
- 			return language;
 
- 		}
 
- 		public static Guid ToGuid (this DocumentLanguage language)
 
- 		{
 
- 			Guid guid;
 
- 			if (!language_guid.TryGetValue (language, out guid))
 
- 				return new Guid ();
 
- 			return guid;
 
- 		}
 
- 		static readonly Guid vendor_ms = new Guid ("994b45c4-e6e9-11d2-903f-00c04fa302a1");
 
- 		public static DocumentLanguageVendor ToVendor (this Guid guid)
 
- 		{
 
- 			if (guid == vendor_ms)
 
- 				return DocumentLanguageVendor.Microsoft;
 
- 			return DocumentLanguageVendor.Other;
 
- 		}
 
- 		public static Guid ToGuid (this DocumentLanguageVendor vendor)
 
- 		{
 
- 			if (vendor == DocumentLanguageVendor.Microsoft)
 
- 				return vendor_ms;
 
- 			return new Guid ();
 
- 		}
 
- 	}
 
- }
 
 
  |