From 7cde491752861a331e091dca601748e9f0741e95 Mon Sep 17 00:00:00 2001 From: Jb Evain Date: Thu, 30 Jul 2015 17:25:12 +0200 Subject: [PATCH] Add support for the portable pdb format --- .gitignore | 1 + Mono.Cecil.Cil/CodeReader.cs | 134 +++- Mono.Cecil.Cil/CodeWriter.cs | 33 +- Mono.Cecil.Cil/Document.cs | 4 +- Mono.Cecil.Cil/Instruction.cs | 7 - Mono.Cecil.Cil/MethodBody.cs | 13 +- Mono.Cecil.Cil/PortablePdb.cs | 382 ++++++++++ Mono.Cecil.Cil/SequencePoint.cs | 26 +- Mono.Cecil.Cil/Symbols.cs | 528 ++++++++++++-- Mono.Cecil.Cil/VariableDefinition.cs | 5 - Mono.Cecil.Cil/VariableReference.cs | 15 - Mono.Cecil.Metadata/BlobHeap.cs | 14 + Mono.Cecil.Metadata/Buffers.cs | 59 +- Mono.Cecil.Metadata/CodedIndex.cs | 3 +- Mono.Cecil.Metadata/GuidHeap.cs | 11 +- Mono.Cecil.Metadata/PdbHeap.cs | 34 + Mono.Cecil.Metadata/TableHeap.cs | 13 +- Mono.Cecil.Metadata/TokenType.cs | 10 + Mono.Cecil.Metadata/Utilities.cs | 135 +++- Mono.Cecil.PE/ByteBuffer.cs | 26 +- Mono.Cecil.PE/Image.cs | 14 +- Mono.Cecil.PE/ImageReader.cs | 100 ++- Mono.Cecil.PE/ImageWriter.cs | 68 +- Mono.Cecil.PE/TextMap.cs | 3 +- Mono.Cecil.csproj | 2 + Mono.Cecil.sln.DotSettings | 2 + Mono.Cecil/AssemblyReader.cs | 628 +++++++++++++++-- Mono.Cecil/AssemblyWriter.cs | 663 +++++++++++++++++- Mono.Cecil/MetadataSystem.cs | 51 ++ Mono.Cecil/MethodDefinition.cs | 31 +- Mono.Cecil/ModuleDefinition.cs | 22 +- Mono.Cecil/TypeParser.cs | 8 +- Mono/Empty.cs | 12 + Test/Mono.Cecil.Tests.csproj | 1 + Test/Mono.Cecil.Tests/BaseTestFixture.cs | 23 +- Test/Mono.Cecil.Tests/Formatter.cs | 14 +- Test/Mono.Cecil.Tests/MethodBodyTests.cs | 13 - Test/Mono.Cecil.Tests/PortablePdbTests.cs | 355 ++++++++++ Test/Mono.Cecil.Tests/VariableTests.cs | 22 +- .../assemblies/EmbeddedPdbTarget.exe | Bin 0 -> 11264 bytes Test/Resources/assemblies/PdbTarget.exe | Bin 0 -> 10240 bytes Test/Resources/assemblies/PdbTarget.pdb | Bin 0 -> 1692 bytes Test/Resources/assemblies/cecil.dll | Bin 0 -> 344064 bytes Test/Resources/assemblies/cecil.pdb | Bin 0 -> 182680 bytes rocks/Test/Mono.Cecil.Rocks.Tests.csproj | 3 + .../Mono.Cecil.Tests/DocCommentIdTests.cs | 10 +- symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs | 105 +-- symbols/mdb/Mono.Cecil.Mdb/MdbWriter.cs | 125 +--- symbols/mdb/Test/Mono.Cecil.Tests/MdbTests.cs | 15 +- symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs | 107 --- symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs | 163 ++--- symbols/pdb/Mono.Cecil.Pdb/PdbWriter.cs | 123 +--- symbols/pdb/Mono.Cecil.Pdb/SymWriter.cs | 2 +- symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs | 58 +- .../Test/Resources/assemblies/PdbTarget.exe | Bin 0 -> 10240 bytes .../Test/Resources/assemblies/PdbTarget.pdb | Bin 0 -> 1692 bytes 56 files changed, 3353 insertions(+), 843 deletions(-) create mode 100644 Mono.Cecil.Cil/PortablePdb.cs create mode 100644 Mono.Cecil.Metadata/PdbHeap.cs create mode 100644 Test/Mono.Cecil.Tests/PortablePdbTests.cs create mode 100644 Test/Resources/assemblies/EmbeddedPdbTarget.exe create mode 100644 Test/Resources/assemblies/PdbTarget.exe create mode 100644 Test/Resources/assemblies/PdbTarget.pdb create mode 100644 Test/Resources/assemblies/cecil.dll create mode 100644 Test/Resources/assemblies/cecil.pdb create mode 100644 symbols/pdb/Test/Resources/assemblies/PdbTarget.exe create mode 100644 symbols/pdb/Test/Resources/assemblies/PdbTarget.pdb diff --git a/.gitignore b/.gitignore index 83f60b740..b497c61dc 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ obj **/test-results/* *Resharper* Mono.Cecil.sln.ide* +TestResults \ No newline at end of file diff --git a/Mono.Cecil.Cil/CodeReader.cs b/Mono.Cecil.Cil/CodeReader.cs index 38bba6616..c4b099344 100644 --- a/Mono.Cecil.Cil/CodeReader.cs +++ b/Mono.Cecil.Cil/CodeReader.cs @@ -86,10 +86,99 @@ void ReadMethodBody () var symbol_reader = reader.module.symbol_reader; - if (symbol_reader != null) { - var instructions = body.Instructions; - symbol_reader.Read (body, offset => GetInstruction (instructions, offset)); + if (symbol_reader != null && method.debug_info == null) + method.debug_info = symbol_reader.Read (method); + + if (method.debug_info != null) + ReadDebugInfo (); + } + + void ReadDebugInfo () + { + ReadSequencePoints (); + + if (method.debug_info.scope != null) + ReadScope (method.debug_info.scope); + + if (method.custom_infos != null) + ReadCustomDebugInformations (method); + } + + void ReadCustomDebugInformations (MethodDefinition method) + { + var custom_infos = method.custom_infos; + + for (int i = 0; i < custom_infos.Count; i++) { + var state_machine_scope = custom_infos [i] as StateMachineScopeDebugInformation; + if (state_machine_scope != null) + ReadStateMachineScope (state_machine_scope); + + var async_method = custom_infos [i] as AsyncMethodBodyDebugInformation; + if (async_method != null) + ReadAsyncMethodBody (async_method); + } + } + + void ReadAsyncMethodBody (AsyncMethodBodyDebugInformation async_method) + { + if (async_method.catch_handler.Offset > -1) + async_method.catch_handler = new InstructionOffset (GetInstruction (async_method.catch_handler.Offset)); + + if (!async_method.yields.IsNullOrEmpty ()) + for (int i = 0; i < async_method.yields.Count; i++) + async_method.yields [i] = new InstructionOffset (GetInstruction (async_method.yields [i].Offset)); + + if (!async_method.resumes.IsNullOrEmpty ()) + for (int i = 0; i < async_method.resumes.Count; i++) + async_method.resumes [i] = new InstructionOffset (GetInstruction (async_method.resumes [i].Offset)); + } + + void ReadStateMachineScope (StateMachineScopeDebugInformation state_machine_scope) + { + state_machine_scope.start = new InstructionOffset (GetInstruction (state_machine_scope.start.Offset)); + + var end_instruction = GetInstruction (state_machine_scope.end.Offset); + state_machine_scope.end = end_instruction == null + ? new InstructionOffset () + : new InstructionOffset (end_instruction); + } + + void ReadSequencePoints () + { + var symbol = method.debug_info; + + for (int i = 0; i < symbol.sequence_points.Count; i++) { + var sequence_point = symbol.sequence_points [i]; + var instruction = GetInstruction (sequence_point.Offset); + if (instruction != null) + sequence_point.offset = new InstructionOffset (instruction); + } + } + + void ReadScopes (Collection scopes) + { + for (int i = 0; i < scopes.Count; i++) + ReadScope (scopes [i]); + } + + void ReadScope (ScopeDebugInformation scope) + { + scope.Start = new InstructionOffset (GetInstruction (scope.Start.Offset)); + + var end_instruction = GetInstruction (scope.End.Offset); + scope.End = end_instruction == null + ? new InstructionOffset () + : new InstructionOffset (end_instruction); + + if (!scope.variables.IsNullOrEmpty ()) { + for (int i = 0; i < scope.variables.Count; i++) { + var variable = scope.variables [i]; + variable.index = new VariableIndex (GetVariable (variable.Index)); + } } + + if (!scope.scopes.IsNullOrEmpty ()) + ReadScopes (scope.scopes); } void ReadFatMethod () @@ -361,10 +450,9 @@ public MetadataToken ReadToken () #if !READ_ONLY - public ByteBuffer PatchRawMethodBody (MethodDefinition method, CodeWriter writer, out MethodSymbols symbols) + public ByteBuffer PatchRawMethodBody (MethodDefinition method, CodeWriter writer, out int code_size, out MetadataToken local_var_token) { var buffer = new ByteBuffer (); - symbols = new MethodSymbols (method.Name); this.method = method; reader.context = method; @@ -373,66 +461,48 @@ public ByteBuffer PatchRawMethodBody (MethodDefinition method, CodeWriter writer var flags = ReadByte (); - MetadataToken local_var_token; - switch (flags & 0x3) { case 0x2: // tiny buffer.WriteByte (flags); local_var_token = MetadataToken.Zero; - symbols.code_size = flags >> 2; - PatchRawCode (buffer, symbols.code_size, writer); + code_size = flags >> 2; + PatchRawCode (buffer, code_size, writer); break; case 0x3: // fat base.position--; - PatchRawFatMethod (buffer, symbols, writer, out local_var_token); + PatchRawFatMethod (buffer, writer, out code_size, out local_var_token); break; default: throw new NotSupportedException (); } - var symbol_reader = reader.module.symbol_reader; - if (symbol_reader != null && writer.metadata.write_symbols) { - symbols.method_token = GetOriginalToken (writer.metadata, method); - symbols.local_var_token = local_var_token; - symbol_reader.Read (symbols); - } - return buffer; } - void PatchRawFatMethod (ByteBuffer buffer, MethodSymbols symbols, CodeWriter writer, out MetadataToken local_var_token) + void PatchRawFatMethod (ByteBuffer buffer, CodeWriter writer, out int code_size, out MetadataToken local_var_token) { var flags = ReadUInt16 (); buffer.WriteUInt16 (flags); buffer.WriteUInt16 (ReadUInt16 ()); - symbols.code_size = ReadInt32 (); - buffer.WriteInt32 (symbols.code_size); + code_size = ReadInt32 (); + buffer.WriteInt32 (code_size); local_var_token = ReadToken (); if (local_var_token.RID > 0) { - var variables = symbols.variables = ReadVariables (local_var_token); + var variables = ReadVariables (local_var_token); buffer.WriteUInt32 (variables != null - ? writer.GetStandAloneSignature (symbols.variables).ToUInt32 () + ? writer.GetStandAloneSignature (variables).ToUInt32 () : 0); } else buffer.WriteUInt32 (0); - PatchRawCode (buffer, symbols.code_size, writer); + PatchRawCode (buffer, code_size, writer); if ((flags & 0x8) != 0) PatchRawSection (buffer, writer.metadata); } - static MetadataToken GetOriginalToken (MetadataBuilder metadata, MethodDefinition method) - { - MetadataToken original; - if (metadata.TryGetOriginalMethodToken (method.token, out original)) - return original; - - return MetadataToken.Zero; - } - void PatchRawCode (ByteBuffer buffer, int code_size, CodeWriter writer) { var metadata = writer.metadata; diff --git a/Mono.Cecil.Cil/CodeWriter.cs b/Mono.Cecil.Cil/CodeWriter.cs index 7f7d0950f..58c9277c6 100644 --- a/Mono.Cecil.Cil/CodeWriter.cs +++ b/Mono.Cecil.Cil/CodeWriter.cs @@ -77,29 +77,21 @@ void WriteUnresolvedMethodBody (MethodDefinition method) { var code_reader = metadata.module.Read (method, (_, reader) => reader.code); - MethodSymbols symbols; - var buffer = code_reader.PatchRawMethodBody (method, this, out symbols); + int code_size; + MetadataToken local_var_token; + var buffer = code_reader.PatchRawMethodBody (method, this, out code_size, out local_var_token); WriteBytes (buffer); - if (symbols.instructions.IsNullOrEmpty ()) + if (method.debug_info == null) return; - symbols.method_token = method.token; - symbols.local_var_token = GetLocalVarToken (buffer, symbols); - var symbol_writer = metadata.symbol_writer; - if (symbol_writer != null) - symbol_writer.Write (symbols); - } - - static MetadataToken GetLocalVarToken (ByteBuffer buffer, MethodSymbols symbols) - { - if (symbols.variables.IsNullOrEmpty ()) - return MetadataToken.Zero; - - buffer.position = 8; - return new MetadataToken (buffer.ReadUInt32 ()); + if (symbol_writer != null) { + method.debug_info.code_size = code_size; + method.debug_info.local_var_token = local_var_token; + symbol_writer.Write (method.debug_info); + } } void WriteResolvedMethodBody (MethodDefinition method) @@ -117,8 +109,11 @@ void WriteResolvedMethodBody (MethodDefinition method) WriteExceptionHandlers (); var symbol_writer = metadata.symbol_writer; - if (symbol_writer != null) - symbol_writer.Write (body); + if (symbol_writer != null && method.debug_info != null) { + method.debug_info.code_size = body.CodeSize; + method.debug_info.local_var_token = body.local_var_token; + symbol_writer.Write (method.debug_info); + } } void WriteFatHeader () diff --git a/Mono.Cecil.Cil/Document.cs b/Mono.Cecil.Cil/Document.cs index d4182e55a..2c2d21e1c 100644 --- a/Mono.Cecil.Cil/Document.cs +++ b/Mono.Cecil.Cil/Document.cs @@ -21,6 +21,7 @@ public enum DocumentHashAlgorithm { None, MD5, SHA1, + SHA256, } public enum DocumentLanguage { @@ -44,7 +45,7 @@ public enum DocumentLanguageVendor { Microsoft, } - public sealed class Document { + public sealed class Document : DebugInformation { string url; @@ -89,6 +90,7 @@ public Document (string url) { this.url = url; this.hash = Empty.Array; + this.token = new MetadataToken (TokenType.Document); } } } diff --git a/Mono.Cecil.Cil/Instruction.cs b/Mono.Cecil.Cil/Instruction.cs index a738a29c9..5fb36049b 100644 --- a/Mono.Cecil.Cil/Instruction.cs +++ b/Mono.Cecil.Cil/Instruction.cs @@ -22,8 +22,6 @@ public sealed class Instruction { internal Instruction previous; internal Instruction next; - SequencePoint sequence_point; - public int Offset { get { return offset; } set { offset = value; } @@ -49,11 +47,6 @@ public Instruction Next { set { next = value; } } - public SequencePoint SequencePoint { - get { return sequence_point; } - set { sequence_point = value; } - } - internal Instruction (int offset, OpCode opCode) { this.offset = offset; diff --git a/Mono.Cecil.Cil/MethodBody.cs b/Mono.Cecil.Cil/MethodBody.cs index 1c8768c49..9540bacea 100644 --- a/Mono.Cecil.Cil/MethodBody.cs +++ b/Mono.Cecil.Cil/MethodBody.cs @@ -15,7 +15,7 @@ namespace Mono.Cecil.Cil { - public sealed class MethodBody : IVariableDefinitionProvider { + public sealed class MethodBody { readonly internal MethodDefinition method; @@ -28,7 +28,6 @@ public sealed class MethodBody : IVariableDefinitionProvider { internal Collection instructions; internal Collection exceptions; internal Collection variables; - Scope scope; public MethodDefinition Method { get { return method; } @@ -73,11 +72,6 @@ public Collection Variables { get { return variables ?? (variables = new VariableDefinitionCollection ()); } } - public Scope Scope { - get { return scope; } - set { scope = value; } - } - public ParameterDefinition ThisParameter { get { if (method == null || method.DeclaringType == null) @@ -114,11 +108,6 @@ public ILProcessor GetILProcessor () } } - public interface IVariableDefinitionProvider { - bool HasVariables { get; } - Collection Variables { get; } - } - class VariableDefinitionCollection : Collection { internal VariableDefinitionCollection () diff --git a/Mono.Cecil.Cil/PortablePdb.cs b/Mono.Cecil.Cil/PortablePdb.cs new file mode 100644 index 000000000..4ed2eca17 --- /dev/null +++ b/Mono.Cecil.Cil/PortablePdb.cs @@ -0,0 +1,382 @@ +// +// 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 Mono.Collections.Generic; + +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; + +namespace Mono.Cecil.Cil { + + public sealed class PortablePdbReaderProvider : ISymbolReaderProvider { + + public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + + using (var file = File.OpenRead (GetPdbFileName (fileName))) + return GetSymbolReader (module, file); + } + + static string GetPdbFileName (string assemblyFileName) + { + return Path.ChangeExtension (assemblyFileName, ".pdb"); + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + + return new PortablePdbReader (ImageReader.ReadPortablePdb (symbolStream), module); + } + } + + public sealed class PortablePdbReader : ISymbolReader { + + readonly Image image; + readonly ModuleDefinition module; + readonly MetadataReader reader; + readonly MetadataReader debug_reader; + readonly MetadataSystem metadata; + + internal PortablePdbReader (Image image, ModuleDefinition module) + { + this.image = image; + this.module = module; + this.reader = module.reader; + this.metadata = module.MetadataSystem; + this.debug_reader = new MetadataReader (image, module, this.reader); + } + + public bool ProcessDebugHeader (ImageDebugDirectory directory, byte [] header) + { + if (image == module.Image) + return true; + + if (header.Length < 24) + return false; + + var magic = ReadInt32 (header, 0); + if (magic != 0x53445352) + return false; + + var buffer = new byte [16]; + Buffer.BlockCopy (header, 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); + + return module_guid == pdb_guid; + } + + static int ReadInt32 (byte [] bytes, int start) + { + return (bytes [start] + | (bytes [start + 1] << 8) + | (bytes [start + 2] << 16) + | (bytes [start + 3] << 24)); + } + + 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 !READ_ONLY + + public sealed class PortablePdbWriterProvider : ISymbolWriterProvider + { + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + + return GetSymbolWriter (module, File.OpenWrite (GetPdbFileName (fileName))); + } + + static string GetPdbFileName (string assemblyFileName) + { + return Path.ChangeExtension (assemblyFileName, ".pdb"); + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + + var metadata = new MetadataBuilder (module, this); + var writer = ImageWriter.CreateDebugWriter (module, metadata, symbolStream); + + return new PortablePdbWriter (metadata, module, writer); + } + } + + sealed class PortablePdbWriter : ISymbolWriter { + + readonly MetadataBuilder pdb_metadata; + readonly ModuleDefinition module; + readonly ImageWriter writer; + + MetadataBuilder module_metadata; + + bool IsEmbedded { get { return writer == null; } } + + public PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module) + { + this.pdb_metadata = pdb_metadata; + this.module = module; + } + + public PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module, ImageWriter writer) + : this (pdb_metadata, module) + { + this.writer = writer; + } + + public void SetModuleMetadata (MetadataBuilder metadata) + { + this.module_metadata = metadata; + + if (module_metadata != pdb_metadata) + this.pdb_metadata.metadata_builder = metadata; + } + + public bool GetDebugHeader (out ImageDebugDirectory directory, out byte [] header) + { + //if (IsEmbedded) { + directory = new ImageDebugDirectory (); + header = Empty.Array; + return false; + //} + + + //throw new NotImplementedException (); + } + + public void Write (MethodDebugInformation info) + { + CheckMethodDebugInformationTable (); + + pdb_metadata.AddMethodDebugInformation (info); + } + + void CheckMethodDebugInformationTable () + { + var mdi = pdb_metadata.table_heap.GetTable (Table.MethodDebugInformation); + if (mdi.length > 0) + return; + + // The MethodDebugInformation table has the same length as the Method table + mdi.rows = new Row [module_metadata.method_rid - 1]; + mdi.length = mdi.rows.Length; + } + + public void Dispose () + { + if (IsEmbedded) + return; + + WritePdbHeap (); + WriteTableHeap (); + + writer.BuildMetadataTextMap (); + writer.WriteMetadataHeader (); + writer.WriteMetadata (); + writer.Dispose (); + } + + void WritePdbHeap () + { + var pdb_heap = pdb_metadata.pdb_heap; + + var id = new ByteBuffer (20); + id.WriteBytes (module.Mvid.ToByteArray ()); + id.WriteUInt32 (0); // Timestamp + + pdb_heap.WriteBytes (id); + 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.WriteTableHeap (); + } + } + +#endif + + static class PdbGuidMapping { + + static readonly Dictionary guid_language = new Dictionary (); + static readonly Dictionary language_guid = new Dictionary (); + + static PdbGuidMapping () + { + AddMapping (DocumentLanguage.C, new Guid (0x63a08714, 0xfc37, 0x11d2, 0x90, 0x4c, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1)); + AddMapping (DocumentLanguage.Cpp, new Guid (0x3a12d0b7, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); + AddMapping (DocumentLanguage.CSharp, new Guid (0x3f5162f8, 0x07c6, 0x11d3, 0x90, 0x53, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1)); + AddMapping (DocumentLanguage.Basic, new Guid (0x3a12d0b8, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); + AddMapping (DocumentLanguage.Java, new Guid (0x3a12d0b4, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); + AddMapping (DocumentLanguage.Cobol, new Guid (0xaf046cd1, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc)); + AddMapping (DocumentLanguage.Pascal, new Guid (0xaf046cd2, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc)); + AddMapping (DocumentLanguage.Cil, new Guid (0xaf046cd3, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc)); + AddMapping (DocumentLanguage.JScript, new Guid (0x3a12d0b6, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); + AddMapping (DocumentLanguage.Smc, new Guid (0xd9b9f7b, 0x6611, 0x11d3, 0xbd, 0x2a, 0x0, 0x0, 0xf8, 0x8, 0x49, 0xbd)); + AddMapping (DocumentLanguage.MCpp, new Guid (0x4b35fde8, 0x07c6, 0x11d3, 0x90, 0x53, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1)); + AddMapping (DocumentLanguage.FSharp, new Guid (0xab4f38c9, 0xb6e6, 0x43ba, 0xbe, 0x3b, 0x58, 0x08, 0x0b, 0x2c, 0xcc, 0xe3)); + } + + static void AddMapping (DocumentLanguage language, Guid guid) + { + guid_language.Add (guid, language); + language_guid.Add (language, guid); + } + + static readonly Guid type_text = new Guid (0x5a869d0b, 0x6611, 0x11d3, 0xbd, 0x2a, 0x00, 0x00, 0xf8, 0x08, 0x49, 0xbd); + + 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 (0x406ea660, 0x64cf, 0x4c82, 0xb6, 0xf0, 0x42, 0xd4, 0x81, 0x72, 0xa7, 0x99); + static readonly Guid hash_sha1 = new Guid (0xff1816ec, 0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60); + static readonly Guid hash_sha256 = new Guid (0x8829d00f, 0x11b8, 0x4213, 0x87, 0x8b, 0x77, 0x0e, 0x85, 0x97, 0xac, 0x16); + + 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; + + 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 (0x994b45c4, 0xe6e9, 0x11d2, 0x90, 0x3f, 0x00, 0xc0, 0x4f, 0xa3, 0x02, 0xa1); + + 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 (); + } + } +} diff --git a/Mono.Cecil.Cil/SequencePoint.cs b/Mono.Cecil.Cil/SequencePoint.cs index 8606744ea..73970542a 100644 --- a/Mono.Cecil.Cil/SequencePoint.cs +++ b/Mono.Cecil.Cil/SequencePoint.cs @@ -8,10 +8,13 @@ // Licensed under the MIT/X11 license. // +using System; + namespace Mono.Cecil.Cil { public sealed class SequencePoint { + internal InstructionOffset offset; Document document; int start_line; @@ -19,6 +22,10 @@ public sealed class SequencePoint { int end_line; int end_column; + public int Offset { + get { return offset.Offset; } + } + public int StartLine { get { return start_line; } set { start_line = value; } @@ -39,13 +46,30 @@ public int EndColumn { set { end_column = value; } } + public bool IsHidden { + get { return start_line == 0xfeefee && start_line == start_column; } + } + public Document Document { get { return document; } set { document = value; } } - public SequencePoint (Document document) + internal SequencePoint (int offset, Document document) { + if (document == null) + throw new ArgumentNullException ("document"); + + this.offset = new InstructionOffset (offset); + this.document = document; + } + + public SequencePoint (Instruction instruction, Document document) + { + if (document == null) + throw new ArgumentNullException ("document"); + + this.offset = new InstructionOffset (instruction); this.document = document; } } diff --git a/Mono.Cecil.Cil/Symbols.cs b/Mono.Cecil.Cil/Symbols.cs index d267c5bc8..d1310966b 100644 --- a/Mono.Cecil.Cil/Symbols.cs +++ b/Mono.Cecil.Cil/Symbols.cs @@ -9,6 +9,7 @@ // using System; +using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using SR = System.Reflection; @@ -29,128 +30,532 @@ public struct ImageDebugDirectory { public int PointerToRawData; } - public sealed class Scope : IVariableDefinitionProvider { + public sealed class ScopeDebugInformation : DebugInformation { - Instruction start; - Instruction end; + internal InstructionOffset start; + internal InstructionOffset end; + internal ImportDebugInformation import; + internal Collection scopes; + internal Collection variables; + internal Collection constants; - Collection scopes; - Collection variables; - - public Instruction Start { + public InstructionOffset Start { get { return start; } set { start = value; } } - public Instruction End { + 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 Scopes { + public Collection Scopes { + get { return scopes ?? (scopes = new Collection ()); } + } + + public bool HasVariables { + get { return !variables.IsNullOrEmpty (); } + } + + public Collection Variables { + get { return variables ?? (variables = new Collection ()); } + } + + public bool HasConstants { + get { return !constants.IsNullOrEmpty (); } + } + + public Collection Constants { + get { return constants ?? (constants = new Collection ()); } + } + + 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 struct InstructionOffset { + + readonly Instruction instruction; + readonly int? offset; + + public int Offset { get { - if (scopes == null) - scopes = new Collection (); + if (instruction != null) + return instruction.Offset; + if (offset.HasValue) + return offset.Value; - return scopes; + throw new NotSupportedException (); } } - public bool HasVariables { - get { return !variables.IsNullOrEmpty (); } + public bool IsEndOfMethod { + get { return instruction == null && !offset.HasValue; } + } + + 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 Collection Variables { + public int Index { get { - if (variables == null) - variables = new Collection (); + if (variable != null) + return variable.Index; + if (index.HasValue) + return index.Value; - return variables; + throw new NotSupportedException (); } } + + 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 struct InstructionSymbol { + public abstract class DebugInformation : ICustomDebugInformationProvider { - public readonly int Offset; - public readonly SequencePoint SequencePoint; + internal MetadataToken token; + internal Collection custom_infos; - public InstructionSymbol (int offset, SequencePoint sequencePoint) + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + public bool HasCustomDebugInformations { + get { return !custom_infos.IsNullOrEmpty (); } + } + + public Collection CustomDebugInformations { + get { return custom_infos ?? (custom_infos = new Collection ()); } + } + + internal DebugInformation () { - this.Offset = offset; - this.SequencePoint = sequencePoint; } } - public sealed class MethodSymbols { + public sealed class VariableDebugInformation : DebugInformation { - internal int code_size; - internal string method_name; - internal MetadataToken method_token; - internal MetadataToken local_var_token; - internal Collection variables; - internal Collection instructions; + string name; + ushort attributes; + internal VariableIndex index; - public bool HasVariables { - get { return !variables.IsNullOrEmpty (); } + public int Index { + get { return index.Index; } } - public Collection Variables { - get { - if (variables == null) - variables = new Collection (); + public string Name { + get { return name; } + set { name = value; } + } - return variables; - } + public VariableAttributes Attributes { + get { return (VariableAttributes) attributes; } + set { attributes = (ushort) value; } } - public Collection Instructions { - get { - if (instructions == null) - instructions = new Collection (); + public bool IsDebuggerHidden { + get { return attributes.GetAttributes ((ushort) VariableAttributes.DebuggerHidden); } + set { attributes = attributes.SetAttributes ((ushort) VariableAttributes.DebuggerHidden, value); } + } - return instructions; - } + 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 { - public int CodeSize { - get { return code_size; } + internal ImportDebugInformation parent; + internal Collection targets; + + public bool HasTargets { + get { return !targets.IsNullOrEmpty (); } } - public string MethodName { - get { return method_name; } + public Collection Targets { + get { return targets ?? (targets = new Collection ()); } } - public MetadataToken MethodToken { - get { return method_token; } + public ImportDebugInformation Parent { + get { return parent; } + set { parent = value; } } - public MetadataToken LocalVarToken { - get { return local_var_token; } + public ImportDebugInformation () + { + this.token = new MetadataToken (TokenType.ImportScope); } + } + + interface ICustomDebugInformationProvider : IMetadataTokenProvider { + bool HasCustomDebugInformations { get; } + Collection CustomDebugInformations { get; } + } + + public enum CustomDebugInformationKind { + Binary, + StateMachineScope, + DynamicVariable, + DefaultNamespace, + AsyncMethodBody, + } + + public abstract class CustomDebugInformation : DebugInformation { + + Guid identifier; - internal MethodSymbols (string methodName) + public Guid Identifier { get { return identifier; } } + + public abstract CustomDebugInformationKind Kind { get; } + + internal CustomDebugInformation (Guid identifier) { - this.method_name = methodName; + 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 MethodSymbols (MetadataToken methodToken) + public override CustomDebugInformationKind Kind { + get { return CustomDebugInformationKind.Binary; } + } + + public BinaryCustomDebugInformation (Guid identifier, byte [] data) + : base (identifier) { - this.method_token = methodToken; + this.data = data; } } - public delegate Instruction InstructionMapper (int offset); + public sealed class AsyncMethodBodyDebugInformation : CustomDebugInformation { + + internal InstructionOffset catch_handler; + internal Collection yields; + internal Collection resumes; + internal MethodDefinition move_next; + + public InstructionOffset CatchHandler { + get { return catch_handler; } + set { catch_handler = value; } + } + + public Collection Yields { + get { return yields ?? (yields = new Collection ()); } + } + + public Collection Resumes { + get { return resumes ?? (resumes = new Collection ()); } + } + + public MethodDefinition MoveNextMethod { + get { return move_next; } + set { move_next = value; } + } + + 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 sealed class StateMachineScopeDebugInformation : CustomDebugInformation { + + internal InstructionOffset start; + internal InstructionOffset end; + + public InstructionOffset Start { + get { return start; } + set { start = value; } + } + + public InstructionOffset End { + get { return end; } + set { end = value; } + } + + public override CustomDebugInformationKind Kind { + get { return CustomDebugInformationKind.StateMachineScope; } + } + + public static Guid KindIdentifier = new Guid ("{6DA9A61E-F8C7-4874-BE62-68BC5630DF71}"); + + internal StateMachineScopeDebugInformation (int start, int end) + : base (KindIdentifier) + { + this.start = new InstructionOffset (start); + this.end = new InstructionOffset (end); + } + + public StateMachineScopeDebugInformation (Instruction start, Instruction end) + : base (KindIdentifier) + { + this.start = new InstructionOffset (start); + this.end = new InstructionOffset (end); + } + } + + public sealed class MethodDebugInformation : DebugInformation { + + internal MethodDefinition method; + internal Collection 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 SequencePoints { + get { return sequence_points ?? (sequence_points = new Collection ()); } + } + + 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 IEnumerable GetScopes () + { + if (scope == null) + return Empty.Array; + + return GetScopes (new[] { scope }); + } + + static IEnumerable GetScopes (IList 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 interface ISymbolReader : IDisposable { bool ProcessDebugHeader (ImageDebugDirectory directory, byte [] header); - void Read (MethodBody body, InstructionMapper mapper); - void Read (MethodSymbols symbols); + MethodDebugInformation Read (MethodDefinition method); } public interface ISymbolReaderProvider { @@ -245,8 +650,7 @@ public static ISymbolWriterProvider GetPlatformWriterProvider () public interface ISymbolWriter : IDisposable { bool GetDebugHeader (out ImageDebugDirectory directory, out byte [] header); - void Write (MethodBody body); - void Write (MethodSymbols symbols); + void Write (MethodDebugInformation info); } public interface ISymbolWriterProvider { diff --git a/Mono.Cecil.Cil/VariableDefinition.cs b/Mono.Cecil.Cil/VariableDefinition.cs index 86887ee11..bd1328464 100644 --- a/Mono.Cecil.Cil/VariableDefinition.cs +++ b/Mono.Cecil.Cil/VariableDefinition.cs @@ -21,11 +21,6 @@ public VariableDefinition (TypeReference variableType) { } - public VariableDefinition (string name, TypeReference variableType) - : base (name, variableType) - { - } - public override VariableDefinition Resolve () { return this; diff --git a/Mono.Cecil.Cil/VariableReference.cs b/Mono.Cecil.Cil/VariableReference.cs index a19216dc8..fb12e8c14 100644 --- a/Mono.Cecil.Cil/VariableReference.cs +++ b/Mono.Cecil.Cil/VariableReference.cs @@ -12,15 +12,9 @@ namespace Mono.Cecil.Cil { public abstract class VariableReference { - string name; internal int index = -1; protected TypeReference variable_type; - public string Name { - get { return name; } - set { name = value; } - } - public TypeReference VariableType { get { return variable_type; } set { variable_type = value; } @@ -31,13 +25,7 @@ public int Index { } internal VariableReference (TypeReference variable_type) - : this (string.Empty, variable_type) - { - } - - internal VariableReference (string name, TypeReference variable_type) { - this.name = name; this.variable_type = variable_type; } @@ -45,9 +33,6 @@ internal VariableReference (string name, TypeReference variable_type) public override string ToString () { - if (!string.IsNullOrEmpty (name)) - return name; - if (index >= 0) return "V_" + index; diff --git a/Mono.Cecil.Metadata/BlobHeap.cs b/Mono.Cecil.Metadata/BlobHeap.cs index 6a07fc635..f63d55319 100644 --- a/Mono.Cecil.Metadata/BlobHeap.cs +++ b/Mono.Cecil.Metadata/BlobHeap.cs @@ -40,5 +40,19 @@ public byte [] Read (uint index) return buffer; } + + public void GetView (uint signature, out byte [] buffer, out int index, out int length) + { + if (signature == 0 || signature > Size - 1) { + buffer = null; + index = length = 0; + return; + } + + buffer = Section.Data; + + index = (int) (signature + Offset); + length = (int) buffer.ReadCompressedUInt32 (ref index); + } } } diff --git a/Mono.Cecil.Metadata/Buffers.cs b/Mono.Cecil.Metadata/Buffers.cs index dcdea1795..80148bca3 100644 --- a/Mono.Cecil.Metadata/Buffers.cs +++ b/Mono.Cecil.Metadata/Buffers.cs @@ -25,11 +25,13 @@ sealed class TableHeapBuffer : HeapBuffer { readonly ModuleDefinition module; readonly MetadataBuilder metadata; - internal MetadataTable [] tables = new MetadataTable [45]; + internal MetadataTable [] tables = new MetadataTable [Mixin.TableCount]; bool large_string; bool large_blob; - readonly int [] coded_index_sizes = new int [13]; + bool large_guid; + + readonly int [] coded_index_sizes = new int [Mixin.CodedIndexCount]; readonly Func counter; public override bool IsEmpty { @@ -87,6 +89,11 @@ public void WriteBlob (uint blob) WriteBySize (blob, large_blob); } + public void WriteGuid (uint guid) + { + WriteBySize (guid, large_guid); + } + public void WriteRID (uint rid, Table table) { var md_table = tables [(int) table]; @@ -169,6 +176,11 @@ byte GetHeapSizes () heap_sizes |= 0x01; } + if (metadata.guid_heap.IsLarge) { + large_guid = true; + heap_sizes |= 0x02; + } + if (metadata.blob_heap.IsLarge) { large_blob = true; heap_sizes |= 0x04; @@ -254,6 +266,37 @@ protected HeapBuffer (int length) } } + sealed class GuidHeapBuffer : HeapBuffer { + + readonly Dictionary guids = new Dictionary (); + + public override bool IsEmpty { + get { return length == 0; } + } + + public GuidHeapBuffer () + : base (16) + { + } + + public uint GetGuidIndex (Guid guid) + { + uint index; + if (guids.TryGetValue (guid, out index)) + return index; + + index = (uint) guids.Count + 1; + WriteGuid (guid); + guids.Add (guid, index); + return index; + } + + void WriteGuid (Guid guid) + { + WriteBytes (guid.ToByteArray ()); + } + } + class StringHeapBuffer : HeapBuffer { readonly Dictionary strings = new Dictionary (StringComparer.Ordinal); @@ -350,6 +393,18 @@ protected override void WriteString (string @string) WriteByte (special); } } + + sealed class PdbHeapBuffer : HeapBuffer { + + public override bool IsEmpty { + get { return false; } + } + + public PdbHeapBuffer () + : base (0) + { + } + } } #endif diff --git a/Mono.Cecil.Metadata/CodedIndex.cs b/Mono.Cecil.Metadata/CodedIndex.cs index 009540d48..2026a8a7d 100644 --- a/Mono.Cecil.Metadata/CodedIndex.cs +++ b/Mono.Cecil.Metadata/CodedIndex.cs @@ -23,6 +23,7 @@ enum CodedIndex { Implementation, CustomAttributeType, ResolutionScope, - TypeOrMethodDef + TypeOrMethodDef, + HasCustomDebugInformation, } } diff --git a/Mono.Cecil.Metadata/GuidHeap.cs b/Mono.Cecil.Metadata/GuidHeap.cs index 74af80e10..9fbe5daf4 100644 --- a/Mono.Cecil.Metadata/GuidHeap.cs +++ b/Mono.Cecil.Metadata/GuidHeap.cs @@ -23,19 +23,16 @@ public GuidHeap (Section section, uint start, uint size) public Guid Read (uint index) { - if (index == 0) - return new Guid (); - const int guid_size = 16; - var buffer = new byte [guid_size]; + if (index == 0 || ((index - 1) + guid_size) > Size) + return new Guid (); - index--; + var buffer = new byte [guid_size]; - Buffer.BlockCopy (Section.Data, (int) (Offset + index), buffer, 0, guid_size); + Buffer.BlockCopy (Section.Data, (int) (Offset + ((index - 1) * guid_size)), buffer, 0, guid_size); return new Guid (buffer); - } } } diff --git a/Mono.Cecil.Metadata/PdbHeap.cs b/Mono.Cecil.Metadata/PdbHeap.cs new file mode 100644 index 000000000..4532e8fde --- /dev/null +++ b/Mono.Cecil.Metadata/PdbHeap.cs @@ -0,0 +1,34 @@ +// +// 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 Mono.Cecil.PE; + +using RID = System.UInt32; + +namespace Mono.Cecil.Metadata { + + sealed class PdbHeap : Heap { + + public byte [] Id; + public RID EntryPoint; + public long TypeSystemTables; + public uint [] TypeSystemTableRows; + + public PdbHeap (Section section, uint offset, uint size) + : base (section, offset, size) + { + } + + public bool HasTable (Table table) + { + return (TypeSystemTables & (1L << (int) table)) != 0; + } + } +} diff --git a/Mono.Cecil.Metadata/TableHeap.cs b/Mono.Cecil.Metadata/TableHeap.cs index 9a83eb3a9..33997ab74 100644 --- a/Mono.Cecil.Metadata/TableHeap.cs +++ b/Mono.Cecil.Metadata/TableHeap.cs @@ -59,6 +59,15 @@ enum Table : byte { GenericParam = 0x2a, MethodSpec = 0x2b, GenericParamConstraint = 0x2c, + + Document = 0x30, + MethodDebugInformation = 0x31, + LocalScope = 0x32, + LocalVariable = 0x33, + LocalConstant = 0x34, + ImportScope = 0x35, + StateMachineMethod = 0x36, + CustomDebugInformation = 0x37, } struct TableInformation { @@ -72,9 +81,7 @@ sealed class TableHeap : Heap { public long Valid; public long Sorted; - public const int TableCount = 45; - - public readonly TableInformation [] Tables = new TableInformation [TableCount]; + public readonly TableInformation [] Tables = new TableInformation [Mixin.TableCount]; public TableInformation this [Table table] { get { return Tables [(int) table]; } diff --git a/Mono.Cecil.Metadata/TokenType.cs b/Mono.Cecil.Metadata/TokenType.cs index 09395fd3e..547f6c647 100644 --- a/Mono.Cecil.Metadata/TokenType.cs +++ b/Mono.Cecil.Metadata/TokenType.cs @@ -34,6 +34,16 @@ public enum TokenType : uint { GenericParam = 0x2a000000, MethodSpec = 0x2b000000, GenericParamConstraint = 0x2c000000, + + Document = 0x30000000, + MethodDebugInformation = 0x31000000, + LocalScope = 0x32000000, + LocalVariable = 0x33000000, + LocalConstant = 0x34000000, + ImportScope = 0x35000000, + StateMachineMethod = 0x36000000, + CustomDebugInformation = 0x37000000, + String = 0x70000000, } } diff --git a/Mono.Cecil.Metadata/Utilities.cs b/Mono.Cecil.Metadata/Utilities.cs index 51f1c351d..3a4330da5 100644 --- a/Mono.Cecil.Metadata/Utilities.cs +++ b/Mono.Cecil.Metadata/Utilities.cs @@ -16,6 +16,9 @@ namespace Mono.Cecil { static partial class Mixin { + public const int TableCount = 58; + public const int CodedIndexCount = 14; + public static uint ReadCompressedUInt32 (this byte [] data, ref int position) { uint integer; @@ -228,6 +231,66 @@ public static MetadataToken GetMetadataToken (this CodedIndex self, uint data) token_type = TokenType.Method; goto ret; default: goto exit; } + case CodedIndex.HasCustomDebugInformation: + rid = data >> 5; + switch (data & 31) { + case 0: + token_type = TokenType.Method; goto ret; + case 1: + token_type = TokenType.Field; goto ret; + case 2: + token_type = TokenType.TypeRef; goto ret; + case 3: + token_type = TokenType.TypeDef; goto ret; + case 4: + token_type = TokenType.Param; goto ret; + case 5: + token_type = TokenType.InterfaceImpl; goto ret; + case 6: + token_type = TokenType.MemberRef; goto ret; + case 7: + token_type = TokenType.Module; goto ret; + case 8: + token_type = TokenType.Permission; goto ret; + case 9: + token_type = TokenType.Property; goto ret; + case 10: + token_type = TokenType.Event; goto ret; + case 11: + token_type = TokenType.Signature; goto ret; + case 12: + token_type = TokenType.ModuleRef; goto ret; + case 13: + token_type = TokenType.TypeSpec; goto ret; + case 14: + token_type = TokenType.Assembly; goto ret; + case 15: + token_type = TokenType.AssemblyRef; goto ret; + case 16: + token_type = TokenType.File; goto ret; + case 17: + token_type = TokenType.ExportedType; goto ret; + case 18: + token_type = TokenType.ManifestResource; goto ret; + case 19: + token_type = TokenType.GenericParam; goto ret; + case 20: + token_type = TokenType.GenericParamConstraint; goto ret; + case 21: + token_type = TokenType.MethodSpec; goto ret; + case 22: + token_type = TokenType.Document; goto ret; + case 23: + token_type = TokenType.LocalScope; goto ret; + case 24: + token_type = TokenType.LocalVariable; goto ret; + case 25: + token_type = TokenType.LocalConstant; goto ret; + case 26: + token_type = TokenType.ImportScope; goto ret; + default: + goto exit; + } default: goto exit; } @@ -432,6 +495,66 @@ public static uint CompressMetadataToken (this CodedIndex self, MetadataToken to default: goto exit; } + case CodedIndex.HasCustomDebugInformation: + ret = token.RID << 5; + switch (token.TokenType) { + case TokenType.Method: + return ret | 0; + case TokenType.Field: + return ret | 1; + case TokenType.TypeRef: + return ret | 2; + case TokenType.TypeDef: + return ret | 3; + case TokenType.Param: + return ret | 4; + case TokenType.InterfaceImpl: + return ret | 5; + case TokenType.MemberRef: + return ret | 6; + case TokenType.Module: + return ret | 7; + case TokenType.Permission: + return ret | 8; + case TokenType.Property: + return ret | 9; + case TokenType.Event: + return ret | 10; + case TokenType.Signature: + return ret | 11; + case TokenType.ModuleRef: + return ret | 12; + case TokenType.TypeSpec: + return ret | 13; + case TokenType.Assembly: + return ret | 14; + case TokenType.AssemblyRef: + return ret | 15; + case TokenType.File: + return ret | 16; + case TokenType.ExportedType: + return ret | 17; + case TokenType.ManifestResource: + return ret | 18; + case TokenType.GenericParam: + return ret | 19; + case TokenType.GenericParamConstraint: + return ret | 20; + case TokenType.MethodSpec: + return ret | 21; + case TokenType.Document: + return ret | 22; + case TokenType.LocalScope: + return ret | 23; + case TokenType.LocalVariable: + return ret | 24; + case TokenType.LocalConstant: + return ret | 25; + case TokenType.ImportScope: + return ret | 26; + default: + goto exit; + } default: goto exit; } @@ -460,7 +583,7 @@ public static int GetSize (this CodedIndex self, Func counter) Table.Method, Table.Field, Table.TypeRef, Table.TypeDef, Table.Param, Table.InterfaceImpl, Table.MemberRef, Table.Module, Table.DeclSecurity, Table.Property, Table.Event, Table.StandAloneSig, Table.ModuleRef, Table.TypeSpec, Table.Assembly, Table.AssemblyRef, Table.File, Table.ExportedType, - Table.ManifestResource, Table.GenericParam + Table.ManifestResource, Table.GenericParam, Table.GenericParamConstraint, Table.MethodSpec, }; break; case CodedIndex.HasFieldMarshal: @@ -503,6 +626,16 @@ public static int GetSize (this CodedIndex self, Func counter) bits = 1; tables = new [] { Table.TypeDef, Table.Method }; break; + case CodedIndex.HasCustomDebugInformation: + bits = 5; + tables = new[] { + Table.Method, Table.Field, Table.TypeRef, Table.TypeDef, Table.Param, Table.InterfaceImpl, Table.MemberRef, + Table.Module, Table.DeclSecurity, Table.Property, Table.Event, Table.StandAloneSig, Table.ModuleRef, + Table.TypeSpec, Table.Assembly, Table.AssemblyRef, Table.File, Table.ExportedType, + Table.ManifestResource, Table.GenericParam, Table.GenericParamConstraint, Table.MethodSpec, + Table.Document, Table.LocalScope, Table.LocalVariable, Table.LocalConstant, Table.ImportScope, + }; + break; default: throw new ArgumentException (); } diff --git a/Mono.Cecil.PE/ByteBuffer.cs b/Mono.Cecil.PE/ByteBuffer.cs index a8dfd16c1..9665c2ae6 100644 --- a/Mono.Cecil.PE/ByteBuffer.cs +++ b/Mono.Cecil.PE/ByteBuffer.cs @@ -122,16 +122,22 @@ public uint ReadCompressedUInt32 () public int ReadCompressedInt32 () { - var value = (int) (ReadCompressedUInt32 () >> 1); - if ((value & 1) == 0) - return value; - if (value < 0x40) - return value - 0x40; - if (value < 0x2000) - return value - 0x2000; - if (value < 0x10000000) - return value - 0x10000000; - return value - 0x20000000; + var b = buffer [position]; + var u = (int) ReadCompressedUInt32 (); + var v = u >> 1; + if ((u & 1) == 0) + return v; + + switch (b & 0xc0) + { + case 0: + case 0x40: + return v - 0x40; + case 0x80: + return v - 0x2000; + default: + return v - 0x10000000; + } } public float ReadSingle () diff --git a/Mono.Cecil.PE/Image.cs b/Mono.Cecil.PE/Image.cs index 31f220f2e..3472fe3dd 100644 --- a/Mono.Cecil.PE/Image.cs +++ b/Mono.Cecil.PE/Image.cs @@ -42,8 +42,9 @@ sealed class Image { public UserStringHeap UserStringHeap; public GuidHeap GuidHeap; public TableHeap TableHeap; + public PdbHeap PdbHeap; - readonly int [] coded_index_sizes = new int [13]; + readonly int [] coded_index_sizes = new int [14]; readonly Func counter; @@ -144,5 +145,16 @@ public ImageDebugDirectory GetDebugHeader (out byte [] header) return directory; } + + public bool HasDebugTables () + { + return HasTable (Table.Document) + || HasTable (Table.MethodDebugInformation) + || HasTable (Table.LocalScope) + || HasTable (Table.LocalVariable) + || HasTable (Table.LocalConstant) + || HasTable (Table.StateMachineMethod) + || HasTable (Table.CustomDebugInformation); + } } } diff --git a/Mono.Cecil.PE/ImageReader.cs b/Mono.Cecil.PE/ImageReader.cs index 78458fc76..00f07595c 100644 --- a/Mono.Cecil.PE/ImageReader.cs +++ b/Mono.Cecil.PE/ImageReader.cs @@ -343,6 +343,9 @@ void ReadMetadata () if (image.TableHeap != null) ReadTableHeap (); + + if (image.PdbHeap != null) + ReadPdbHeap (); } void ReadMetadataStream (Section section) @@ -371,6 +374,9 @@ void ReadMetadataStream (Section section) case "#US": image.UserStringHeap = new UserStringHeap (section, start, size); break; + case "#Pdb": + image.PdbHeap = new PdbHeap (section, start, size); + break; } } @@ -399,7 +405,7 @@ void ReadTableHeap () // Sorted 8 heap.Sorted = ReadInt64 (); - for (int i = 0; i < TableHeap.TableCount; i++) { + for (int i = 0; i < Mixin.TableCount; i++) { if (!heap.HasTable ((Table) i)) continue; @@ -436,12 +442,13 @@ void ComputeTableInformations () uint offset = (uint) BaseStream.Position - image.MetadataSection.PointerToRawData; // header int stridx_size = image.StringHeap.IndexSize; + int guididx_size = image.GuidHeap.IndexSize; int blobidx_size = image.BlobHeap != null ? image.BlobHeap.IndexSize : 2; var heap = image.TableHeap; var tables = heap.Tables; - for (int i = 0; i < TableHeap.TableCount; i++) { + for (int i = 0; i < Mixin.TableCount; i++) { var table = (Table) i; if (!heap.HasTable (table)) continue; @@ -451,7 +458,7 @@ void ComputeTableInformations () case Table.Module: size = 2 // Generation + stridx_size // Name - + (image.GuidHeap.IndexSize * 3); // Mvid, EncId, EncBaseId + + (guididx_size * 3); // Mvid, EncId, EncBaseId break; case Table.TypeRef: size = GetCodedIndexSize (CodedIndex.ResolutionScope) // ResolutionScope @@ -639,6 +646,45 @@ void ComputeTableInformations () size = GetTableIndexSize (Table.GenericParam) // Owner + GetCodedIndexSize (CodedIndex.TypeDefOrRef); // Constraint break; + case Table.Document: + size = blobidx_size // Name + + guididx_size // HashAlgorithm + + blobidx_size // Hash + + guididx_size; // Language + break; + case Table.MethodDebugInformation: + size = GetTableIndexSize (Table.Document) // Document + + blobidx_size; // SequencePoints + break; + case Table.LocalScope: + size = GetTableIndexSize (Table.Method) // Method + + GetTableIndexSize (Table.ImportScope) // ImportScope + + GetTableIndexSize (Table.LocalVariable) // VariableList + + GetTableIndexSize (Table.LocalConstant) // ConstantList + + 4 * 2; // StartOffset, Length + break; + case Table.LocalVariable: + size = 2 // Attributes + + 2 // Index + + stridx_size; // Name + break; + case Table.LocalConstant: + size = stridx_size // Name + + blobidx_size; // Signature + break; + case Table.ImportScope: + size = GetTableIndexSize (Table.ImportScope) // Parent + + blobidx_size; + break; + case Table.StateMachineMethod: + size = GetTableIndexSize (Table.Method) // MoveNextMethod + + GetTableIndexSize (Table.Method); // KickOffMethod + break; + case Table.CustomDebugInformation: + size = GetCodedIndexSize (CodedIndex.HasCustomDebugInformation) // Parent + + guididx_size // Kind + + blobidx_size; // Value + break; default: throw new NotSupportedException (); } @@ -650,7 +696,29 @@ void ComputeTableInformations () } } - public static Image ReadImageFrom (Stream stream) + void ReadPdbHeap () + { + var heap = image.PdbHeap; + + uint start = heap.Section.PointerToRawData; + + MoveTo (heap.Offset + start); + + heap.Id = ReadBytes (20); + heap.EntryPoint = ReadUInt32 (); + heap.TypeSystemTables = ReadInt64 (); + heap.TypeSystemTableRows = new uint [Mixin.TableCount]; + + for (int i = 0; i < Mixin.TableCount; i++) { + var table = (Table) i; + if (!heap.HasTable (table)) + continue; + + heap.TypeSystemTableRows [i] = ReadUInt32 (); + } + } + + public static Image ReadImage (Stream stream) { try { var reader = new ImageReader (stream); @@ -660,5 +728,29 @@ public static Image ReadImageFrom (Stream stream) throw new BadImageFormatException (stream.GetFullyQualifiedName (), e); } } + + public static Image ReadPortablePdb (Stream stream) + { + try { + var reader = new ImageReader (stream); + var length = (uint) stream.Length; + + reader.image.Sections = new[] { + new Section { + PointerToRawData = 0, + SizeOfRawData = length, + VirtualAddress = 0, + VirtualSize = length, + Data = stream.ReadAll (), + } + }; + + reader.metadata = new DataDirectory (0, length); + reader.ReadMetadata (); + return reader.image; + } catch (EndOfStreamException e) { + throw new BadImageFormatException (stream.GetFullyQualifiedName (), e); + } + } } } diff --git a/Mono.Cecil.PE/ImageWriter.cs b/Mono.Cecil.PE/ImageWriter.cs index fc952b14b..ae59040c9 100644 --- a/Mono.Cecil.PE/ImageWriter.cs +++ b/Mono.Cecil.PE/ImageWriter.cs @@ -26,6 +26,8 @@ sealed class ImageWriter : BinaryStreamWriter { readonly MetadataBuilder metadata; readonly TextMap text_map; + readonly string runtime_version; + ImageDebugDirectory debug_directory; byte [] debug_data; @@ -49,16 +51,21 @@ sealed class ImageWriter : BinaryStreamWriter { ushort sections; - ImageWriter (ModuleDefinition module, MetadataBuilder metadata, Stream stream) + ImageWriter (ModuleDefinition module, string runtime_version, MetadataBuilder metadata, Stream stream, bool metadataOnly = false) : base (stream) { this.module = module; + this.runtime_version = runtime_version; + this.text_map = metadata.text_map; this.metadata = metadata; + if (metadataOnly) + return; + this.pe64 = module.Architecture == TargetArchitecture.AMD64 || module.Architecture == TargetArchitecture.IA64; this.has_reloc = module.Architecture == TargetArchitecture.I386; this.GetDebugHeader (); this.GetWin32Resources (); - this.text_map = BuildTextMap (); + this.BuildTextMap (); this.sections = (ushort) (has_reloc ? 2 : 1); // text + reloc? this.time_stamp = (uint) DateTime.UtcNow.Subtract (new DateTime (1970, 1, 1)).TotalSeconds; } @@ -96,11 +103,19 @@ Section GetImageResourceSection () public static ImageWriter CreateWriter (ModuleDefinition module, MetadataBuilder metadata, Stream stream) { - var writer = new ImageWriter (module, metadata, stream); + var writer = new ImageWriter (module, module.runtime_version, metadata, stream); writer.BuildSections (); return writer; } + public static ImageWriter CreateDebugWriter (ModuleDefinition module, MetadataBuilder metadata, Stream stream) + { + var writer = new ImageWriter (module, "PDB V1.0", metadata, stream, metadataOnly: true); + var length = metadata.text_map.GetLength (); + writer.text = new Section { SizeOfRawData = length, VirtualSize = length }; + return writer; + } + void BuildSections () { var has_win32_resources = win32_resources != null; @@ -484,14 +499,14 @@ uint GetMetadataLength () return text_map.GetRVA (TextSegment.DebugDirectory) - text_map.GetRVA (TextSegment.MetadataHeader); } - void WriteMetadataHeader () + public void WriteMetadataHeader () { WriteUInt32 (0x424a5342); // Signature WriteUInt16 (1); // MajorVersion WriteUInt16 (1); // MinorVersion WriteUInt32 (0); // Reserved - var version = GetZeroTerminatedString (module.runtime_version); + var version = GetZeroTerminatedString (runtime_version); WriteUInt32 ((uint) version.Length); WriteBytes (version); WriteUInt16 (0); // Flags @@ -504,6 +519,7 @@ void WriteMetadataHeader () WriteStreamHeader (ref offset, TextSegment.UserStringHeap, "#US"); WriteStreamHeader (ref offset, TextSegment.GuidHeap, "#GUID"); WriteStreamHeader (ref offset, TextSegment.BlobHeap, "#Blob"); + WriteStreamHeader (ref offset, TextSegment.PdbHeap, "#Pdb"); } ushort GetStreamCount () @@ -513,7 +529,8 @@ ushort GetStreamCount () + 1 // #Strings + (metadata.user_string_heap.IsEmpty ? 0 : 1) // #US + 1 // GUID - + (metadata.blob_heap.IsEmpty ? 0 : 1)); // #Blob + + (metadata.blob_heap.IsEmpty ? 0 : 1) + + (metadata.pdb_heap == null ? 0 : 1)); // #Blob } void WriteStreamHeader (ref uint offset, TextSegment heap, string name) @@ -552,30 +569,25 @@ static byte [] GetString (string @string, int length) return bytes; } - void WriteMetadata () + public void WriteMetadata () { WriteHeap (TextSegment.TableHeap, metadata.table_heap); WriteHeap (TextSegment.StringHeap, metadata.string_heap); WriteHeap (TextSegment.UserStringHeap, metadata.user_string_heap); - WriteGuidHeap (); + WriteHeap (TextSegment.GuidHeap, metadata.guid_heap); WriteHeap (TextSegment.BlobHeap, metadata.blob_heap); + WriteHeap (TextSegment.PdbHeap, metadata.pdb_heap); } void WriteHeap (TextSegment heap, HeapBuffer buffer) { - if (buffer.IsEmpty) + if (buffer == null || buffer.IsEmpty) return; MoveToRVA (heap); WriteBuffer (buffer); } - void WriteGuidHeap () - { - MoveToRVA (TextSegment.GuidHeap); - WriteBytes (module.Mvid.ToByteArray ()); - } - void WriteDebugDirectory () { WriteInt32 (debug_directory.Characteristics); @@ -670,9 +682,9 @@ public void WriteImage () WriteReloc (); } - TextMap BuildTextMap () + void BuildTextMap () { - var map = metadata.text_map; + var map = text_map; map.AddMap (TextSegment.Code, metadata.code.length, !pe64 ? 4 : 16); map.AddMap (TextSegment.Resources, metadata.resources.length, 8); @@ -681,12 +693,7 @@ TextMap BuildTextMap () metadata.table_heap.FixupData (map.GetRVA (TextSegment.Data)); map.AddMap (TextSegment.StrongNameSignature, GetStrongNameLength (), 4); - map.AddMap (TextSegment.MetadataHeader, GetMetadataHeaderLength (module.RuntimeVersion)); - map.AddMap (TextSegment.TableHeap, metadata.table_heap.length, 4); - map.AddMap (TextSegment.StringHeap, metadata.string_heap.length, 4); - map.AddMap (TextSegment.UserStringHeap, metadata.user_string_heap.IsEmpty ? 0 : metadata.user_string_heap.length, 4); - map.AddMap (TextSegment.GuidHeap, 16); - map.AddMap (TextSegment.BlobHeap, metadata.blob_heap.IsEmpty ? 0 : metadata.blob_heap.length, 4); + BuildMetadataTextMap (); int debug_dir_len = 0; if (!debug_data.IsNullOrEmpty ()) { @@ -703,7 +710,7 @@ TextMap BuildTextMap () map.AddMap (TextSegment.ImportDirectory, new Range (start, 0)); map.AddMap (TextSegment.ImportHintNameTable, new Range (start, 0)); map.AddMap (TextSegment.StartupStub, new Range (start, 0)); - return map; + return; } RVA import_dir_rva = map.GetNextRVA (TextSegment.DebugDirectory); @@ -719,8 +726,19 @@ TextMap BuildTextMap () map.AddMap (TextSegment.ImportDirectory, new Range (import_dir_rva, import_dir_len)); map.AddMap (TextSegment.ImportHintNameTable, new Range (import_hnt_rva, 0)); map.AddMap (TextSegment.StartupStub, new Range (startup_stub_rva, GetStartupStubLength ())); + } + + public void BuildMetadataTextMap () + { + var map = text_map; - return map; + map.AddMap (TextSegment.MetadataHeader, GetMetadataHeaderLength (module.RuntimeVersion)); + map.AddMap (TextSegment.TableHeap, metadata.table_heap.length, 4); + map.AddMap (TextSegment.StringHeap, metadata.string_heap.length, 4); + map.AddMap (TextSegment.UserStringHeap, metadata.user_string_heap.IsEmpty ? 0 : metadata.user_string_heap.length, 4); + map.AddMap (TextSegment.GuidHeap, metadata.guid_heap.length, 4); + map.AddMap (TextSegment.BlobHeap, metadata.blob_heap.IsEmpty ? 0 : metadata.blob_heap.length, 4); + map.AddMap (TextSegment.PdbHeap, metadata.pdb_heap == null ? 0 : metadata.pdb_heap.length, 4); } uint GetStartupStubLength () diff --git a/Mono.Cecil.PE/TextMap.cs b/Mono.Cecil.PE/TextMap.cs index 955754308..614691b6a 100644 --- a/Mono.Cecil.PE/TextMap.cs +++ b/Mono.Cecil.PE/TextMap.cs @@ -31,6 +31,7 @@ enum TextSegment { UserStringHeap, GuidHeap, BlobHeap, + PdbHeap, // End Metadata DebugDirectory, @@ -41,7 +42,7 @@ enum TextSegment { sealed class TextMap { - readonly Range [] map = new Range [16 /*Enum.GetValues (typeof (TextSegment)).Length*/]; + readonly Range [] map = new Range [17 /*Enum.GetValues (typeof (TextSegment)).Length*/]; public void AddMap (TextSegment segment, int length) { diff --git a/Mono.Cecil.csproj b/Mono.Cecil.csproj index e14a1b9aa..753a14bd1 100644 --- a/Mono.Cecil.csproj +++ b/Mono.Cecil.csproj @@ -10,6 +10,7 @@ + @@ -27,6 +28,7 @@ + diff --git a/Mono.Cecil.sln.DotSettings b/Mono.Cecil.sln.DotSettings index faf57070f..b1aed5ead 100644 --- a/Mono.Cecil.sln.DotSettings +++ b/Mono.Cecil.sln.DotSettings @@ -32,6 +32,8 @@ C:\sources\cecil\Mono.Cecil.sln.DotSettings True 1 + True True + True True None \ No newline at end of file diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs index 1d91110f5..3e16a3196 100644 --- a/Mono.Cecil/AssemblyReader.cs +++ b/Mono.Cecil/AssemblyReader.cs @@ -35,6 +35,7 @@ protected ModuleReader (Image image, ReadingMode mode) } protected abstract void ReadModule (); + public abstract void ReadSymbols (ModuleDefinition module); protected void ReadModuleManifest (MetadataReader reader) { @@ -58,7 +59,7 @@ void ReadAssembly (MetadataReader reader) assembly.main_module = module; } - public static ModuleDefinition CreateModuleFrom (Image image, ReaderParameters parameters) + public static ModuleDefinition CreateModule (Image image, ReaderParameters parameters) { var reader = CreateModuleReader (image, parameters.ReadingMode); var module = reader.module; @@ -82,6 +83,8 @@ public static ModuleDefinition CreateModuleFrom (Image image, ReaderParameters p ReadSymbols (module, parameters); + reader.ReadSymbols (module); + return module; } @@ -103,6 +106,9 @@ static void ReadSymbols (ModuleDefinition module, ReaderParameters parameters) module.ReadSymbols (reader); } + + if (module.Image.HasDebugTables ()) + module.ReadSymbols (new PortablePdbReader (module.Image, module)); } static ModuleReader CreateModuleReader (Image image, ReadingMode mode) @@ -120,7 +126,7 @@ static ModuleReader CreateModuleReader (Image image, ReadingMode mode) sealed class ImmediateModuleReader : ModuleReader { - bool resolve; + bool resolve_attributes; public ImmediateModuleReader (Image image) : base (image, ReadingMode.Immediate) @@ -131,25 +137,25 @@ protected override void ReadModule () { this.module.Read (this.module, (module, reader) => { ReadModuleManifest (reader); - ReadModule (module, resolve: true); + ReadModule (module, resolve_attributes: true); return module; }); } - public void ReadModule (ModuleDefinition module, bool resolve) + public void ReadModule (ModuleDefinition module, bool resolve_attributes) { - this.resolve = resolve; + this.resolve_attributes = resolve_attributes; if (module.HasAssemblyReferences) - Read (module.AssemblyReferences); + Mixin.Read (module.AssemblyReferences); if (module.HasResources) - Read (module.Resources); + Mixin.Read (module.Resources); if (module.HasModuleReferences) - Read (module.ModuleReferences); + Mixin.Read (module.ModuleReferences); if (module.HasTypes) ReadTypes (module.Types); if (module.HasExportedTypes) - Read (module.ExportedTypes); + Mixin.Read (module.ExportedTypes); ReadCustomAttributes (module); @@ -172,13 +178,13 @@ void ReadType (TypeDefinition type) ReadGenericParameters (type); if (type.HasInterfaces) - Read (type.Interfaces); + Mixin.Read (type.Interfaces); if (type.HasNestedTypes) ReadTypes (type.NestedTypes); if (type.HasLayoutInfo) - Read (type.ClassSize); + Mixin.Read (type.ClassSize); if (type.HasFields) ReadFields (type); @@ -207,7 +213,7 @@ void ReadGenericParameters (IGenericParameterProvider provider) var parameter = parameters [i]; if (parameter.HasConstraints) - Read (parameter.Constraints); + Mixin.Read (parameter.Constraints); ReadCustomAttributes (parameter); } @@ -220,13 +226,13 @@ void ReadSecurityDeclarations (ISecurityDeclarationProvider provider) var security_declarations = provider.SecurityDeclarations; - if (!resolve) + if (!resolve_attributes) return; for (int i = 0; i < security_declarations.Count; i++) { var security_declaration = security_declarations [i]; - Read (security_declaration.SecurityAttributes); + Mixin.Read (security_declaration.SecurityAttributes); } } @@ -237,13 +243,13 @@ void ReadCustomAttributes (ICustomAttributeProvider provider) var custom_attributes = provider.CustomAttributes; - if (!resolve) + if (!resolve_attributes) return; for (int i = 0; i < custom_attributes.Count; i++) { var custom_attribute = custom_attributes [i]; - Read (custom_attribute.ConstructorArguments); + Mixin.Read (custom_attribute.ConstructorArguments); } } @@ -255,16 +261,16 @@ void ReadFields (TypeDefinition type) var field = fields [i]; if (field.HasConstant) - Read (field.Constant); + Mixin.Read (field.Constant); if (field.HasLayoutInfo) - Read (field.Offset); + Mixin.Read (field.Offset); if (field.RVA > 0) - Read (field.InitialValue); + Mixin.Read (field.InitialValue); if (field.HasMarshalInfo) - Read (field.MarshalInfo); + Mixin.Read (field.MarshalInfo); ReadCustomAttributes (field); } @@ -283,20 +289,20 @@ void ReadMethods (TypeDefinition type) ReadParameters (method); if (method.HasOverrides) - Read (method.Overrides); + Mixin.Read (method.Overrides); if (method.IsPInvokeImpl) - Read (method.PInvokeInfo); + Mixin.Read (method.PInvokeInfo); ReadSecurityDeclarations (method); ReadCustomAttributes (method); var return_type = method.MethodReturnType; if (return_type.HasConstant) - Read (return_type.Constant); + Mixin.Read (return_type.Constant); if (return_type.HasMarshalInfo) - Read (return_type.MarshalInfo); + Mixin.Read (return_type.MarshalInfo); ReadCustomAttributes (return_type); } @@ -310,10 +316,10 @@ void ReadParameters (MethodDefinition method) var parameter = parameters [i]; if (parameter.HasConstant) - Read (parameter.Constant); + Mixin.Read (parameter.Constant); if (parameter.HasMarshalInfo) - Read (parameter.MarshalInfo); + Mixin.Read (parameter.MarshalInfo); ReadCustomAttributes (parameter); } @@ -326,10 +332,10 @@ void ReadProperties (TypeDefinition type) for (int i = 0; i < properties.Count; i++) { var property = properties [i]; - Read (property.GetMethod); + Mixin.Read (property.GetMethod); if (property.HasConstant) - Read (property.Constant); + Mixin.Read (property.Constant); ReadCustomAttributes (property); } @@ -342,14 +348,42 @@ void ReadEvents (TypeDefinition type) for (int i = 0; i < events.Count; i++) { var @event = events [i]; - Read (@event.AddMethod); + Mixin.Read (@event.AddMethod); ReadCustomAttributes (@event); } } - static void Read (object collection) + public override void ReadSymbols (ModuleDefinition module) + { + if (module.symbol_reader == null) + return; + + ReadTypesSymbols (module.Types, module.symbol_reader); + } + + void ReadTypesSymbols (Collection types, ISymbolReader symbol_reader) { + for (int i = 0; i < types.Count; i++) { + var type = types [i]; + + if (type.HasNestedTypes) + ReadTypesSymbols (type.NestedTypes, symbol_reader); + + if (type.HasMethods) + ReadMethodsSymbols (type, symbol_reader); + } + } + + void ReadMethodsSymbols (TypeDefinition type, ISymbolReader symbol_reader) + { + var methods = type.Methods; + for (int i = 0; i < methods.Count; i++) { + var method = methods [i]; + + if (method.HasBody && method.debug_info == null) + method.debug_info = symbol_reader.Read (method); + } } } @@ -367,6 +401,10 @@ protected override void ReadModule () return module; }); } + + public override void ReadSymbols (ModuleDefinition module) + { + } } sealed class MetadataReader : ByteBuffer { @@ -378,6 +416,8 @@ sealed class MetadataReader : ByteBuffer { internal IGenericContext context; internal CodeReader code; + readonly MetadataReader metadata_reader; + uint Position { get { return (uint) base.position; } set { base.position = (int) value; } @@ -392,6 +432,16 @@ public MetadataReader (ModuleDefinition module) this.code = new CodeReader (image.MetadataSection, this); } + public MetadataReader (Image image, ModuleDefinition module, MetadataReader metadata_reader) + : base (image.MetadataSection.Data) + { + this.image = image; + this.module = module; + this.metadata = module.MetadataSystem; + this.code = new CodeReader (image.MetadataSection, this); + this.metadata_reader = metadata_reader; + } + int GetCodedIndexSize (CodedIndex index) { return image.GetCodedIndexSize (index); @@ -431,6 +481,18 @@ uint ReadBlobIndex () return ReadByIndexSize (blob_heap != null ? blob_heap.IndexSize : 2); } + void GetBlobView (uint signature, out byte [] blob, out int index, out int count) + { + var blob_heap = image.BlobHeap; + if (blob_heap == null) { + blob = null; + index = count = 0; + return; + } + + blob_heap.GetView (signature, out blob, out index, out count); + } + string ReadString () { return image.StringHeap.Read (ReadByIndexSize (image.StringHeap.IndexSize)); @@ -441,6 +503,11 @@ uint ReadStringIndex () return ReadByIndexSize (image.StringHeap.IndexSize); } + Guid ReadGuid () + { + return image.GuidHeap.Read (ReadByIndexSize (image.GuidHeap.IndexSize)); + } + uint ReadTableIndex (Table table) { return ReadByIndexSize (image.GetTableIndexSize (table)); @@ -497,7 +564,7 @@ public ModuleDefinition Populate (ModuleDefinition module) Advance (2); // Generation module.Name = ReadString (); - module.Mvid = image.GuidHeap.Read (ReadByIndexSize (image.GuidHeap.IndexSize)); + module.Mvid = ReadGuid (); return module; } @@ -737,8 +804,8 @@ void CompleteTypes () for (int i = 0; i < types.Length; i++) { var type = types [i]; - InitializeCollection (type.Fields); - InitializeCollection (type.Methods); + Mixin.Read (type.Fields); + Mixin.Read (type.Methods); } } @@ -1917,9 +1984,7 @@ static void AddRange (Dictionary ranges, MetadataToken return; } - slots = slots.Resize (slots.Length + 1); - slots [slots.Length - 1] = range; - ranges [owner] = slots; + ranges [owner] = slots.Add(range); } public bool HasGenericConstraints (GenericParameter generic_parameter) @@ -2086,6 +2151,9 @@ public IMetadataTokenProvider LookupToken (MetadataToken token) if (rid == 0) return null; + if (metadata_reader != null) + return metadata_reader.LookupToken (token); + IMetadataTokenProvider element; var position = this.position; var context = this.context; @@ -2139,7 +2207,7 @@ FieldDefinition LookupField (uint rid) if (type == null) return null; - InitializeCollection (type.Fields); + Mixin.Read (type.Fields); return metadata.GetFieldDefinition (rid); } @@ -2161,7 +2229,7 @@ MethodDefinition LookupMethod (uint rid) if (type == null) return null; - InitializeCollection (type.Methods); + Mixin.Read (type.Methods); return metadata.GetMethodDefinition (rid); } @@ -2341,24 +2409,35 @@ public object ReadConstant (IConstantProvider owner) metadata.Constants.Remove (owner.MetadataToken); - switch (row.Col1) { + return ReadConstantValue (row.Col1, row.Col2); + } + + object ReadConstantValue (ElementType etype, uint signature) + { + switch (etype) { case ElementType.Class: case ElementType.Object: return null; case ElementType.String: - return ReadConstantString (ReadBlob (row.Col2)); + return ReadConstantString (signature); default: - return ReadConstantPrimitive (row.Col1, row.Col2); + return ReadConstantPrimitive (etype, signature); } } - static string ReadConstantString (byte [] blob) + string ReadConstantString (uint signature) { - var length = blob.Length; - if ((length & 1) == 1) - length--; + byte [] blob; + int index, count; + + GetBlobView (signature, out blob, out index, out count); + if (count == 0) + return string.Empty; - return Encoding.Unicode.GetString (blob, 0, length); + if ((count & 1) == 1) + count--; + + return Encoding.Unicode.GetString (blob, index, count); } object ReadConstantPrimitive (ElementType type, uint signature) @@ -2591,7 +2670,6 @@ public void ReadSecurityDeclarationSignature (SecurityDeclaration declaration) void ReadXmlSecurityDeclaration (uint signature, SecurityDeclaration declaration) { - var blob = ReadBlob (signature); var attributes = new Collection (1); var attribute = new SecurityAttribute ( @@ -2603,7 +2681,7 @@ void ReadXmlSecurityDeclaration (uint signature, SecurityDeclaration declaration "XML", new CustomAttributeArgument ( module.TypeSystem.String, - Encoding.Unicode.GetString (blob, 0, blob.Length)))); + ReadUnicodeStringBlob (signature)))); attributes.Add (attribute); @@ -2660,7 +2738,7 @@ IMetadataScope GetExportedTypeScope (MetadataToken token) switch (token.TokenType) { case TokenType.AssemblyRef: InitializeAssemblyReferences (); - scope = metadata.AssemblyReferences [(int) token.RID - 1]; + scope = metadata.GetAssemblyNameReference (token.RID); break; case TokenType.File: InitializeModuleReferences (); @@ -2695,15 +2773,386 @@ ModuleReference GetModuleReferenceFromFile (MetadataToken token) return reference; } - static void InitializeCollection (object o) + void InitializeDocuments () { + if (metadata.Documents != null) + return; + + int length = MoveTo (Table.Document); + + var documents = metadata.Documents = new Document [length]; + + for (uint i = 1; i <= length; i++) { + var name_index = ReadBlobIndex (); + var hash_algorithm = ReadGuid (); + var hash = ReadBlob (); + var language = ReadGuid (); + + var signature = ReadSignature (name_index); + var name = signature.ReadDocumentName (); + + documents [i - 1] = new Document (name) { + HashAlgorithm = hash_algorithm.ToHashAlgorithm (), + Hash = hash, + Language = language.ToLanguage (), + token = new MetadataToken (TokenType.Document, i), + }; + } + } + + public Collection ReadSequencePoints (MethodDefinition method) + { + InitializeDocuments (); + + if (!MoveTo (Table.MethodDebugInformation, method.MetadataToken.RID)) + return new Collection (); + + var document = metadata.GetDocument (ReadTableIndex (Table.Document)); + var reader = ReadSignature (ReadBlobIndex ()); + + return reader.ReadSequencePoints (document); + } + + void InitializeLocalScopes () + { + if (metadata.LocalScopes != null) + return; + + InitializeMethods (); + + int length = MoveTo (Table.LocalScope); + + metadata.LocalScopes = new Dictionary []> (); + + for (uint i = 1; i <= length; i++) { + var method = ReadTableIndex (Table.Method); + var import = ReadTableIndex (Table.ImportScope); + var variables = ReadListRange (i, Table.LocalScope, Table.LocalVariable); + var constants = ReadListRange (i, Table.LocalScope, Table.LocalConstant); + var scope_start = ReadUInt32 (); + var scope_length = ReadUInt32 (); + + metadata.SetLocalScopes (method, AddMapping (metadata.LocalScopes, method, new Row (import, variables, constants, scope_start, scope_length, i))); + } + } + + public ScopeDebugInformation ReadScope (MethodDefinition method) + { + InitializeLocalScopes (); + InitializeImportScopes (); + + Row [] records; + if (!metadata.TryGetLocalScopes (method, out records)) + return null; + + var method_scope = null as ScopeDebugInformation; + + for (int i = 0; i < records.Length; i++) { + var scope = ReadLocalScope (records [i]); + + if (i == 0) { + method_scope = scope; + continue; + } + + if (!AddScope (method_scope.scopes, scope)) + method_scope.Scopes.Add (scope); + } + + return method_scope; + } + + static bool AddScope (Collection scopes, ScopeDebugInformation scope) + { + if (scopes.IsNullOrEmpty ()) + return false; + + foreach (var sub_scope in scopes) { + if (sub_scope.HasScopes && AddScope (sub_scope.Scopes, scope)) + return true; + + if (scope.Start.Offset >= sub_scope.Start.Offset && scope.End.Offset <= sub_scope.End.Offset) { + sub_scope.Scopes.Add (scope); + return true; + } + } + + return false; + } + + ScopeDebugInformation ReadLocalScope (Row record) + { + var scope = new ScopeDebugInformation + { + start = new InstructionOffset ((int) record.Col4), + end = new InstructionOffset ((int) (record.Col4 + record.Col5)), + token = new MetadataToken (TokenType.LocalScope, record.Col6), + }; + + if (record.Col1 > 0) + scope.import = metadata.GetImportScope (record.Col1); + + if (record.Col2.Length > 0) { + scope.variables = new Collection ((int) record.Col2.Length); + for (uint i = 0; i < record.Col2.Length; i++) + scope.variables.Add (ReadLocalVariable (record.Col2.Start + i)); + } + + if (record.Col3.Length > 0) { + scope.constants = new Collection ((int) record.Col3.Length); + for (uint i = 0; i < record.Col3.Length; i++) + scope.constants.Add (ReadLocalConstant (record.Col3.Start + i)); + } + + return scope; + } + + VariableDebugInformation ReadLocalVariable (uint rid) + { + if (!MoveTo (Table.LocalVariable, rid)) + return null; + + var attributes = (VariableAttributes) ReadUInt16 (); + var index = ReadUInt16 (); + var name = ReadString (); + + var variable = new VariableDebugInformation (index, name) { Attributes = attributes, token = new MetadataToken (TokenType.LocalVariable, rid) }; + variable.custom_infos = GetCustomDebugInformation (variable); + return variable; + } + + ConstantDebugInformation ReadLocalConstant (uint rid) + { + if (!MoveTo (Table.LocalConstant, rid)) + return null; + + var name = ReadString (); + var signature = ReadSignature (ReadBlobIndex ()); + var type = signature.ReadTypeSignature (); + + object value; + if (type.etype == ElementType.String) { + if (signature.buffer [signature.position] != 0xff) + value = Encoding.Unicode.GetString (signature.ReadBytes ((int) (signature.sig_length - (signature.position - signature.start)))); + else + value = null; + } else if (type.etype == ElementType.Object) { + value = null; + } else if (type.IsTypeOf ("System", "Decimal")) { + var b = signature.ReadByte (); + value = new decimal (signature.ReadInt32 (), signature.ReadInt32 (), signature.ReadInt32 (), (b & 0x80) != 0, (byte) (b & 0x7f)); + } else if (type.IsTypeOf ("System", "DateTime")) { + value = new DateTime (signature.ReadInt64()); + } else + value = signature.ReadConstantSignature (type.etype); + + var constant = new ConstantDebugInformation (name, type, value) { token = new MetadataToken (TokenType.LocalConstant, rid) }; + constant.custom_infos = GetCustomDebugInformation (constant); + return constant; + } + + void InitializeImportScopes () + { + if (metadata.ImportScopes != null) + return; + + var length = MoveTo (Table.ImportScope); + + metadata.ImportScopes = new ImportDebugInformation [length]; + + for (int i = 1; i <= length; i++) { + ReadTableIndex (Table.ImportScope); + + var import = new ImportDebugInformation (); + import.token = new MetadataToken (TokenType.ImportScope, i); + + var signature = ReadSignature (ReadBlobIndex ()); + while (signature.CanReadMore ()) + import.Targets.Add (ReadImportTarget (signature)); + + metadata.ImportScopes [i - 1] = import; + } + + MoveTo (Table.ImportScope); + + for (int i = 0; i < length; i++) { + var parent = ReadTableIndex (Table.ImportScope); + + ReadBlobIndex (); + + if (parent != 0) + metadata.ImportScopes [i].Parent = metadata.GetImportScope (parent); + } + } + + public string ReadUTF8StringBlob (uint signature) + { + return ReadStringBlob (signature, Encoding.UTF8); + } + + string ReadUnicodeStringBlob (uint signature) + { + return ReadStringBlob (signature, Encoding.Unicode); + } + + string ReadStringBlob (uint signature, Encoding encoding) + { + byte [] blob; + int index, count; + + + GetBlobView (signature, out blob, out index, out count); + if (count == 0) + return string.Empty; + + return encoding.GetString (blob, index, count); + } + + ImportTarget ReadImportTarget (SignatureReader signature) + { + AssemblyNameReference reference = null; + string @namespace = null; + string alias = null; + TypeReference type = null; + + var kind = (ImportTargetKind) signature.ReadCompressedUInt32 (); + switch (kind) { + case ImportTargetKind.ImportNamespace: + @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.ImportNamespaceInAssembly: + reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ()); + @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.ImportType: + type = signature.ReadTypeToken (); + break; + case ImportTargetKind.ImportXmlNamespaceWithAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.ImportAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.DefineAssemblyAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.DefineNamespaceAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.DefineNamespaceInAssemblyAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ()); + @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.DefineTypeAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + type = signature.ReadTypeToken (); + break; + } + + return new ImportTarget (kind) { + alias = alias, + type = type, + @namespace = @namespace, + reference = reference, + }; + } + + void InitializeStateMachineMethods () + { + if (metadata.StateMachineMethods != null) + return; + + var length = MoveTo (Table.StateMachineMethod); + + metadata.StateMachineMethods = new Dictionary (length); + + for (int i = 0; i < length; i++) + metadata.StateMachineMethods.Add (ReadTableIndex (Table.Method), ReadTableIndex (Table.Method)); + } + + public MethodDefinition ReadStateMachineKickoffMethod (MethodDefinition method) + { + InitializeStateMachineMethods (); + + uint rid; + if (!metadata.TryGetStateMachineKickOffMethod (method, out rid)) + return null; + + return GetMethodDefinition (rid); + } + + void InitializeCustomDebugInformations () + { + if (metadata.CustomDebugInformations != null) + return; + + var length = MoveTo (Table.CustomDebugInformation); + + metadata.CustomDebugInformations = new Dictionary []> (); + + for (uint i = 1; i <= length; i++) { + var token = ReadMetadataToken (CodedIndex.HasCustomDebugInformation); + var info = new Row (ReadGuid (), ReadBlobIndex (), i); + + Row [] infos; + metadata.CustomDebugInformations.TryGetValue (token, out infos); + metadata.CustomDebugInformations [token] = infos.Add (info); + } + } + + public Collection GetCustomDebugInformation (ICustomDebugInformationProvider provider) + { + InitializeCustomDebugInformations (); + + Row [] rows; + if (!metadata.CustomDebugInformations.TryGetValue (provider.MetadataToken, out rows)) + return null; + + var infos = new Collection (rows.Length); + + for (int i = 0; i < rows.Length; i++) { + if (rows [i].Col1 == StateMachineScopeDebugInformation.KindIdentifier) { + var signature = ReadSignature (rows [i].Col2); + infos.Add (new StateMachineScopeDebugInformation (signature.ReadInt32 (), signature.ReadInt32 ())); + } else if (rows [i].Col1 == AsyncMethodBodyDebugInformation.KindIdentifier) { + var signature = ReadSignature (rows [i].Col2); + + var catch_offset = signature.ReadInt32 () - 1; + var yields = new Collection (); + var resumes = new Collection (); + uint move_next_rid = 0; + + while (signature.CanReadMore ()) { + yields.Add (new InstructionOffset (signature.ReadInt32 ())); + resumes.Add (new InstructionOffset (signature.ReadInt32 ())); + move_next_rid = signature.ReadCompressedUInt32 (); + } + + var async_body = new AsyncMethodBodyDebugInformation (catch_offset); + async_body.yields = yields; + async_body.resumes = resumes; + async_body.move_next = GetMethodDefinition (move_next_rid); + + infos.Add (async_body); + } else { + infos.Add (new BinaryCustomDebugInformation (rows [i].Col1, ReadBlob (rows [i].Col2))); + } + + infos [i].token = new MetadataToken (TokenType.CustomDebugInformation, rows [i].Col3); + } + + return infos; } } sealed class SignatureReader : ByteBuffer { readonly MetadataReader reader; - readonly uint start, sig_length; + readonly internal uint start, sig_length; TypeSystem TypeSystem { get { return reader.module.TypeSystem; } @@ -2827,6 +3276,11 @@ public TypeReference ReadTypeSignature () return ReadTypeSignature ((ElementType) ReadByte ()); } + public TypeReference ReadTypeToken () + { + return GetTypeDefOrRef (ReadTypeTokenSignature ()); + } + TypeReference ReadTypeSignature (ElementType etype) { switch (etype) { @@ -3238,6 +3692,78 @@ string ReadUTF8String () return @string; } + public string ReadDocumentName () + { + var separator = (char) buffer [position]; + position++; + + var builder = new StringBuilder (); + for (int i = 0; CanReadMore (); i++) { + if (i > 0 && separator != 0) + builder.Append (separator); + + builder.Append (reader.ReadUTF8StringBlob (ReadCompressedUInt32 ())); + } + + return builder.ToString (); + } + + public Collection ReadSequencePoints (Document document) + { + var sequence_points = new Collection (); + + ReadCompressedUInt32 (); // local_sig_token + + if (document == null) + document = reader.metadata.GetDocument (ReadCompressedUInt32 ()); + + var offset = 0; + var start_line = 0; + var start_column = 0; + var first_non_hidden = true; + + for (var i = 0; CanReadMore (); i++) { + var delta_il = (int) ReadCompressedUInt32 (); + if (i > 0 && delta_il == 0) { + document = reader.metadata.GetDocument (ReadCompressedUInt32 ()); + continue; + } + + offset += delta_il; + + var delta_lines = (int) ReadCompressedUInt32 (); + var delta_columns = delta_lines == 0 + ? (int) ReadCompressedUInt32 () + : ReadCompressedInt32 (); + + if (delta_lines == 0 && delta_columns == 0) { + sequence_points.Add (new SequencePoint (offset, document) { + StartLine = 0xfeefee, + StartColumn = 0xfeefee, + }); + continue; + } + + if (first_non_hidden) { + start_line = (int) ReadCompressedUInt32 (); + start_column = (int) ReadCompressedUInt32 (); + } else { + start_line += ReadCompressedInt32 (); + start_column += ReadCompressedInt32 (); + } + + sequence_points.Add (new SequencePoint (offset, document) { + StartLine = start_line, + StartColumn = start_column, + EndLine = start_line + delta_lines, + EndColumn = start_column + delta_columns, + }); + first_non_hidden = false; + } + + return sequence_points; + } + public bool CanReadMore () { return position - start < sig_length; diff --git a/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil/AssemblyWriter.cs index 2fd8e2c00..e35e2d5a5 100644 --- a/Mono.Cecil/AssemblyWriter.cs +++ b/Mono.Cecil/AssemblyWriter.cs @@ -23,11 +23,13 @@ using CodedRID = System.UInt32; using StringIndex = System.UInt32; using BlobIndex = System.UInt32; +using GuidIndex = System.UInt32; namespace Mono.Cecil { #if !READ_ONLY + using ModuleRow = Row; using TypeRefRow = Row; using TypeDefRow = Row; using FieldRow = Row; @@ -58,6 +60,14 @@ namespace Mono.Cecil { using GenericParamRow = Row; using MethodSpecRow = Row; using GenericParamConstraintRow = Row; + using DocumentRow = Row; + using MethodDebugInformationRow = Row; + using LocalScopeRow = Row; + using LocalVariableRow = Row; + using LocalConstantRow = Row; + using ImportScopeRow = Row; + using StateMachineMethodRow = Row; + using CustomDebugInformationRow = Row; static class ModuleWriter { @@ -68,7 +78,8 @@ public static void WriteModuleTo (ModuleDefinition module, Stream stream, Writer if (module.HasImage && module.ReadingMode == ReadingMode.Deferred) { var immediate_reader = new ImmediateModuleReader (module.Image); - immediate_reader.ReadModule (module, resolve: false); + immediate_reader.ReadModule (module, resolve_attributes: false); + immediate_reader.ReadSymbols (module); } module.MetadataSystem.Clear (); @@ -88,8 +99,8 @@ public static void WriteModuleTo (ModuleDefinition module, Stream stream, Writer module.Attributes |= ModuleAttributes.StrongNameSigned; } #endif - var metadata = new MetadataBuilder (module, fq_name, - symbol_writer_provider, symbol_writer); + + var metadata = new MetadataBuilder (module, fq_name, symbol_writer_provider, symbol_writer); BuildMetadata (module, metadata); @@ -97,15 +108,15 @@ public static void WriteModuleTo (ModuleDefinition module, Stream stream, Writer module.symbol_reader.Dispose (); var writer = ImageWriter.CreateWriter (module, metadata, stream); - writer.WriteImage (); + if (metadata.symbol_writer != null) + metadata.symbol_writer.Dispose (); + #if !PCL if (parameters.StrongNameKeyPair != null) CryptoService.StrongName (stream, writer, parameters.StrongNameKeyPair); #endif - if (symbol_writer != null) - symbol_writer.Dispose (); } static void BuildMetadata (ModuleDefinition module, MetadataBuilder metadata) @@ -200,13 +211,13 @@ protected int Compare (uint x, uint y) public abstract int Compare (TRow x, TRow y); } - sealed class ModuleTable : OneRowTable { + sealed class ModuleTable : OneRowTable { public override void Write (TableHeapBuffer buffer) { buffer.WriteUInt16 (0); // Generation - buffer.WriteString (row); // Name - buffer.WriteUInt16 (1); // Mvid + buffer.WriteString (row.Col1); // Name + buffer.WriteGuid (row.Col2); // Mvid buffer.WriteUInt16 (0); // EncId buffer.WriteUInt16 (0); // EncBaseId } @@ -671,6 +682,102 @@ public override void Write (TableHeapBuffer buffer) } } + sealed class DocumentTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteBlob (rows [i].Col1); // Name + buffer.WriteGuid (rows [i].Col2); // HashAlgorithm + buffer.WriteBlob (rows [i].Col3); // Hash + buffer.WriteGuid (rows [i].Col4); // Language + } + } + } + + sealed class MethodDebugInformationTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.Document); // Document + buffer.WriteBlob (rows [i].Col2); // SequencePoints + } + } + } + + sealed class LocalScopeTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.Method); // Method + buffer.WriteRID (rows [i].Col2, Table.ImportScope); // ImportScope + buffer.WriteRID (rows [i].Col3, Table.LocalVariable); // VariableList + buffer.WriteRID (rows [i].Col4, Table.LocalConstant); // ConstantList + buffer.WriteUInt32 (rows [i].Col5); // StartOffset + buffer.WriteUInt32 (rows [i].Col6); // Length + } + } + } + + sealed class LocalVariableTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes + buffer.WriteUInt16 (rows [i].Col2); // Index + buffer.WriteString (rows [i].Col3); // Name + } + } + } + + sealed class LocalConstantTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteString (rows [i].Col1); // Name + buffer.WriteBlob (rows [i].Col2); // Signature + } + } + } + + sealed class ImportScopeTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.ImportScope); // Parent + buffer.WriteBlob (rows [i].Col2); // Imports + } + } + } + + sealed class StateMachineMethodTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.Method); // MoveNextMethod + buffer.WriteRID (rows [i].Col2, Table.Method); // KickoffMethod + } + } + } + + sealed class CustomDebugInformationTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomDebugInformation); // Parent + buffer.WriteGuid (rows [i].Col2); // Kind + buffer.WriteBlob (rows [i].Col3); // Value + } + } + } + sealed class MetadataBuilder { readonly internal ModuleDefinition module; @@ -684,24 +791,27 @@ sealed class MetadataBuilder { readonly Dictionary member_ref_map; readonly Dictionary method_spec_map; readonly Collection generic_parameters; - readonly Dictionary method_def_map; readonly internal CodeWriter code; readonly internal DataBuffer data; readonly internal ResourceBuffer resources; readonly internal StringHeapBuffer string_heap; + readonly internal GuidHeapBuffer guid_heap; readonly internal UserStringHeapBuffer user_string_heap; readonly internal BlobHeapBuffer blob_heap; readonly internal TableHeapBuffer table_heap; + readonly internal PdbHeapBuffer pdb_heap; internal MetadataToken entry_point; - RID type_rid = 1; - RID field_rid = 1; - RID method_rid = 1; - RID param_rid = 1; - RID property_rid = 1; - RID event_rid = 1; + internal RID type_rid = 1; + internal RID field_rid = 1; + internal RID method_rid = 1; + internal RID param_rid = 1; + internal RID property_rid = 1; + internal RID event_rid = 1; + internal RID local_variable_rid = 1; + internal RID local_constant_rid = 1; readonly TypeRefTable type_ref_table; readonly TypeDefTable type_def_table; @@ -721,6 +831,22 @@ sealed class MetadataBuilder { readonly TypeSpecTable typespec_table; readonly MethodSpecTable method_spec_table; + readonly bool portable_pdb; + + internal MetadataBuilder metadata_builder; + + readonly DocumentTable document_table; + readonly MethodDebugInformationTable method_debug_information_table; + readonly LocalScopeTable local_scope_table; + readonly LocalVariableTable local_variable_table; + readonly LocalConstantTable local_constant_table; + readonly ImportScopeTable import_scope_table; + readonly StateMachineMethodTable state_machine_method_table; + readonly CustomDebugInformationTable custom_debug_information_table; + + readonly Dictionary import_scope_map; + readonly Dictionary document_map; + readonly internal bool write_symbols; public MetadataBuilder (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider, ISymbolWriter symbol_writer) @@ -729,12 +855,25 @@ public MetadataBuilder (ModuleDefinition module, string fq_name, ISymbolWriterPr this.text_map = CreateTextMap (); this.fq_name = fq_name; this.symbol_writer_provider = symbol_writer_provider; + + if (symbol_writer == null && module.HasImage && module.Image.HasDebugTables ()) { + symbol_writer = new PortablePdbWriter (this, module); + } + this.symbol_writer = symbol_writer; this.write_symbols = symbol_writer != null; + + var pdb_writer = symbol_writer as PortablePdbWriter; + if (pdb_writer != null) { + portable_pdb = true; + pdb_writer.SetModuleMetadata (this); + } + this.code = new CodeWriter (this); this.data = new DataBuffer (); this.resources = new ResourceBuffer (); this.string_heap = new StringHeapBuffer (); + this.guid_heap = new GuidHeapBuffer (); this.user_string_heap = new UserStringHeapBuffer (); this.blob_heap = new BlobHeapBuffer (); this.table_heap = new TableHeapBuffer (module, this); @@ -763,8 +902,50 @@ public MetadataBuilder (ModuleDefinition module, string fq_name, ISymbolWriterPr member_ref_map = new Dictionary (row_equality_comparer); method_spec_map = new Dictionary (row_equality_comparer); generic_parameters = new Collection (); - if (write_symbols) - method_def_map = new Dictionary (); + + if (!portable_pdb) + return; + + this.document_table = GetTable (Table.Document); + this.method_debug_information_table = GetTable (Table.MethodDebugInformation); + this.local_scope_table = GetTable (Table.LocalScope); + this.local_variable_table = GetTable (Table.LocalVariable); + this.local_constant_table = GetTable (Table.LocalConstant); + this.import_scope_table = GetTable (Table.ImportScope); + this.state_machine_method_table = GetTable (Table.StateMachineMethod); + this.custom_debug_information_table = GetTable (Table.CustomDebugInformation); + + this.document_map = new Dictionary (StringComparer.Ordinal); + this.import_scope_map = new Dictionary (row_equality_comparer); + } + + public MetadataBuilder (ModuleDefinition module, PortablePdbWriterProvider writer_provider) + { + this.module = module; + this.text_map = new TextMap (); + this.symbol_writer_provider = writer_provider; + this.portable_pdb = true; + + this.string_heap = new StringHeapBuffer (); + this.guid_heap = new GuidHeapBuffer (); + this.user_string_heap = new UserStringHeapBuffer (); + this.blob_heap = new BlobHeapBuffer (); + this.table_heap = new TableHeapBuffer (module, this); + this.pdb_heap = new PdbHeapBuffer(); + + this.document_table = GetTable (Table.Document); + this.method_debug_information_table = GetTable (Table.MethodDebugInformation); + this.local_scope_table = GetTable (Table.LocalScope); + this.local_variable_table = GetTable (Table.LocalVariable); + this.local_constant_table = GetTable (Table.LocalConstant); + this.import_scope_table = GetTable (Table.ImportScope); + this.state_machine_method_table = GetTable (Table.StateMachineMethod); + this.custom_debug_information_table = GetTable (Table.CustomDebugInformation); + + var row_equality_comparer = new RowEqualityComparer (); + + this.document_map = new Dictionary (); + this.import_scope_map = new Dictionary (row_equality_comparer); } TextMap CreateTextMap () @@ -788,6 +969,11 @@ uint GetStringIndex (string @string) return string_heap.GetStringIndex (@string); } + uint GetGuidIndex (Guid guid) + { + return guid_heap.GetGuidIndex (guid); + } + uint GetBlobIndex (ByteBuffer blob) { if (blob.length == 0) @@ -814,7 +1000,8 @@ public void BuildMetadata () void BuildModule () { var table = GetTable (Table.Module); - table.row = GetStringIndex (module.Name); + table.row.Col1 = GetStringIndex (module.Name); + table.row.Col2 = GetGuidIndex (module.Mvid); var assembly = module.Assembly; @@ -1106,20 +1293,8 @@ void AttachMethodsDefToken (TypeDefinition type) { var methods = type.Methods; type.methods_range.Length = (uint) methods.Count; - for (int i = 0; i < methods.Count; i++) { - var method = methods [i]; - var new_token = new MetadataToken (TokenType.Method, method_rid++); - - if (write_symbols && method.token != MetadataToken.Zero) - method_def_map.Add (new_token, method.token); - - method.token = new_token; - } - } - - public bool TryGetOriginalMethodToken (MetadataToken new_token, out MetadataToken original) - { - return method_def_map.TryGetValue (new_token, out original); + for (int i = 0; i < methods.Count; i++) + methods [i].token = new MetadataToken (TokenType.Method, method_rid++); } MetadataToken GetTypeToken (TypeReference type) @@ -1972,6 +2147,9 @@ public MetadataToken LookupToken (IMetadataTokenProvider provider) if (provider == null) throw new ArgumentNullException (); + if (metadata_builder != null) + return metadata_builder.LookupToken (provider); + var member = provider as MemberReference; if (member == null || member.Module != module) throw CreateForeignMemberException (member); @@ -1997,6 +2175,342 @@ public MetadataToken LookupToken (IMetadataTokenProvider provider) throw new NotSupportedException (); } } + + public void AddMethodDebugInformation (MethodDebugInformation method_info) + { + if (method_info.HasSequencePoints) + AddSequencePoints (method_info); + + if (method_info.Scope != null) + AddLocalScope (method_info, method_info.Scope); + + if (method_info.StateMachineKickOffMethod != null) + AddStateMachineMethod (method_info); + + AddCustomDebugInformations (method_info.Method); + } + + void AddStateMachineMethod (MethodDebugInformation method_info) + { + state_machine_method_table.AddRow (new StateMachineMethodRow (method_info.Method.MetadataToken.RID, method_info.StateMachineKickOffMethod.MetadataToken.RID)); + } + + void AddLocalScope (MethodDebugInformation method_info, ScopeDebugInformation scope) + { + var rid = local_scope_table.AddRow (new LocalScopeRow ( + method_info.Method.MetadataToken.RID, + AddImportScope (scope.Import), + local_variable_rid, + local_constant_rid, + (uint) scope.Start.Offset, + (uint) ((scope.End.IsEndOfMethod ? method_info.code_size : scope.End.Offset) - scope.Start.Offset))); + + scope.token = new MetadataToken (TokenType.LocalScope, rid); + + AddCustomDebugInformations (scope); + + if (scope.HasVariables) + AddLocalVariables (scope); + + if (scope.HasConstants) + AddLocalConstants (scope); + + if (scope.Import != null) + AddImportScope (scope.Import); + + for (int i = 0; i < scope.Scopes.Count; i++) + AddLocalScope (method_info, scope.Scopes [i]); + } + + void AddLocalVariables (ScopeDebugInformation scope) + { + for (int i = 0; i < scope.Variables.Count; i++) { + var variable = scope.Variables [i]; + local_variable_table.AddRow (new LocalVariableRow (variable.Attributes, (ushort) variable.Index, GetStringIndex (variable.Name))); + variable.token = new MetadataToken (TokenType.LocalVariable, local_variable_rid); + local_variable_rid++; + + AddCustomDebugInformations (variable); + } + } + + void AddLocalConstants (ScopeDebugInformation scope) + { + for (int i = 0; i < scope.Constants.Count; i++) { + var constant = scope.Constants [i]; + local_constant_table.AddRow (new LocalConstantRow (GetStringIndex (constant.Name), GetBlobIndex (GetConstantSignature(constant)))); + constant.token = new MetadataToken (TokenType.LocalConstant, local_constant_rid); + local_constant_rid++; + } + } + + SignatureWriter GetConstantSignature (ConstantDebugInformation constant) + { + var type = constant.ConstantType; + + var signature = CreateSignatureWriter (); + signature.WriteTypeSignature (type); + + if (type.IsTypeOf ("System", "Decimal")) { + var bits = decimal.GetBits ((decimal) constant.Value); + + var low = (uint) bits [0]; + var mid = (uint) bits [1]; + var high = (uint) bits [2]; + + var scale = (byte) (bits [3] >> 16); + var negative = (bits [3] & 0x80000000) != 0; + + signature.WriteByte ((byte) (scale | (negative ? 0x80 : 0x00))); + signature.WriteUInt32 (low); + signature.WriteUInt32 (mid); + signature.WriteUInt32 (high); + + return signature; + } + + if (type.IsTypeOf ("System", "DateTime")) { + var date = (DateTime) constant.Value; + signature.WriteInt64 (date.Ticks); + return signature; + } + + signature.WriteBytes (GetConstantSignature (type.etype, constant.Value)); + + return signature; + } + + void AddCustomDebugInformations (ICustomDebugInformationProvider provider) + { + if (!provider.HasCustomDebugInformations) + return; + + var custom_infos = provider.CustomDebugInformations; + + for (int i = 0; i < custom_infos.Count; i++) { + var custom_info = custom_infos [i]; + switch (custom_info.Kind) { + case CustomDebugInformationKind.Binary: + var binary_info = (BinaryCustomDebugInformation) custom_info; + AddCustomDebugInformation (provider, binary_info, GetBlobIndex (binary_info.Data)); + break; + case CustomDebugInformationKind.AsyncMethodBody: + AddAsyncMethodBodyDebugInformation (provider, (AsyncMethodBodyDebugInformation) custom_info); + break; + case CustomDebugInformationKind.StateMachineScope: + AddStateMachineScopeDebugInformation (provider, (StateMachineScopeDebugInformation) custom_info); + break; + default: + throw new NotImplementedException (); + } + } + } + + void AddStateMachineScopeDebugInformation (ICustomDebugInformationProvider provider, StateMachineScopeDebugInformation state_machine_scope) + { + var method_info = ((MethodDefinition) provider).DebugInformation; + + var signature = CreateSignatureWriter (); + signature.WriteUInt32 ((uint) state_machine_scope.Start.Offset); + + var end_offset = state_machine_scope.End.IsEndOfMethod + ? method_info.code_size + : state_machine_scope.End.Offset; + + signature.WriteUInt32 ((uint) (end_offset - state_machine_scope.Start.Offset)); + + AddCustomDebugInformation (provider, state_machine_scope, signature); + } + + void AddAsyncMethodBodyDebugInformation (ICustomDebugInformationProvider provider, AsyncMethodBodyDebugInformation async_method) + { + var signature = CreateSignatureWriter (); + signature.WriteUInt32 ((uint) async_method.catch_handler.Offset + 1); + + for (int i = 0; i < async_method.yields.Count; i++) { + signature.WriteUInt32 ((uint) async_method.yields [i].Offset); + signature.WriteUInt32 ((uint) async_method.resumes [i].Offset); + signature.WriteCompressedUInt32 (async_method.move_next.MetadataToken.RID); + } + + AddCustomDebugInformation (provider, async_method, signature); + } + + void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, SignatureWriter signature) + { + AddCustomDebugInformation (provider, custom_info, GetBlobIndex (signature)); + } + + void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, uint blob_index) + { + var rid = custom_debug_information_table.AddRow (new CustomDebugInformationRow ( + MakeCodedRID (provider.MetadataToken, CodedIndex.HasCustomDebugInformation), + GetGuidIndex (custom_info.Identifier), + blob_index)); + + custom_info.token = new MetadataToken (TokenType.CustomDebugInformation, rid); + } + + uint AddImportScope (ImportDebugInformation import) + { + uint parent = 0; + if (import.Parent != null) + parent = AddImportScope (import.Parent); + + uint targets_index = 0; + if (import.HasTargets) { + var signature = CreateSignatureWriter (); + + for (int i = 0; i < import.Targets.Count; i++) + AddImportTarget (import.Targets [i], signature); + + targets_index = GetBlobIndex (signature); + } + + var row = new ImportScopeRow (parent, targets_index); + + MetadataToken import_token; + if (import_scope_map.TryGetValue (row, out import_token)) + return import_token.RID; + + import_token = new MetadataToken (TokenType.ImportScope, import_scope_table.AddRow (row)); + import_scope_map.Add (row, import_token); + + return import_token.RID; + } + + void AddImportTarget (ImportTarget target, SignatureWriter signature) + { + signature.WriteCompressedUInt32 ((uint)target.kind); + + switch (target.kind) { + case ImportTargetKind.ImportNamespace: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); + break; + case ImportTargetKind.ImportNamespaceInAssembly: + signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID); + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); + break; + case ImportTargetKind.ImportType: + signature.WriteTypeToken (target.type); + break; + case ImportTargetKind.ImportXmlNamespaceWithAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); + break; + case ImportTargetKind.ImportAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + break; + case ImportTargetKind.DefineAssemblyAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID); + break; + case ImportTargetKind.DefineNamespaceAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); + break; + case ImportTargetKind.DefineNamespaceInAssemblyAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID); + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); + break; + case ImportTargetKind.DefineTypeAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + signature.WriteTypeToken (target.type); + break; + } + } + + uint GetUTF8StringBlobIndex (string s) + { + return GetBlobIndex (Encoding.UTF8.GetBytes (s)); + } + + public MetadataToken GetDocumentToken (Document document) + { + MetadataToken token; + if (document_map.TryGetValue (document.Url, out token)) + return token; + + token = new MetadataToken (TokenType.Document, document_table.AddRow ( + new DocumentRow (GetBlobIndex (GetDocumentNameSignature (document)), + GetGuidIndex (document.HashAlgorithm.ToGuid ()), + GetBlobIndex (document.Hash), + GetGuidIndex (document.Language.ToGuid ())))); + + document.token = token; + + document_map.Add (document.Url, token); + + return token; + } + + SignatureWriter GetDocumentNameSignature (Document document) + { + var name = document.Url; + var signature = CreateSignatureWriter (); + + char separator; + if (!TryGetDocumentNameSeparator (name, out separator)) { + signature.WriteByte (0); + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (name)); + return signature; + } + + signature.WriteByte ((byte) separator); + + var parts = name.Split (new [] { separator }, StringSplitOptions.RemoveEmptyEntries); + for (int i = 0; i < parts.Length; i++) + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (parts [i])); + + return signature; + } + + static bool TryGetDocumentNameSeparator (string path, out char separator) + { + const char unix = '/'; + const char win = '\\'; + const char zero = (char) 0; + + separator = zero; + if (string.IsNullOrEmpty (path)) + return false; + + int unix_count = 0; + int win_count = 0; + + for (int i = 0; i < path.Length; i++) { + if (path [i] == unix) + unix_count++; + else if (path [i] == win) + win_count++; + } + + if (unix_count == 0 && win_count == 0) + return false; + + if (unix_count >= win_count) { + separator = unix; + return true; + } + + separator = win; + return true; + } + + void AddSequencePoints (MethodDebugInformation info) + { + var rid = info.Method.MetadataToken.RID; + + Document document; + if (info.TryGetUniqueDocument (out document)) + method_debug_information_table.rows [rid - 1].Col1 = GetDocumentToken (document).RID; + + var signature = CreateSignatureWriter (); + signature.WriteSequencePoints (info); + + method_debug_information_table.rows [rid - 1].Col2 = GetBlobIndex (signature); + } } sealed class SignatureWriter : ByteBuffer { @@ -2066,6 +2580,11 @@ uint MakeTypeDefOrRefCodedRID (TypeReference type) return CodedIndex.TypeDefOrRef.CompressMetadataToken (metadata.LookupToken (type)); } + public void WriteTypeToken (TypeReference type) + { + WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type)); + } + public void WriteTypeSignature (TypeReference type) { if (type == null) @@ -2220,7 +2739,10 @@ bool TryWriteElementType (TypeReference type) public void WriteConstantString (string value) { - WriteBytes (Encoding.Unicode.GetBytes (value)); + if (value != null) + WriteBytes (Encoding.Unicode.GetBytes (value)); + else + WriteByte (0xff); } public void WriteConstantPrimitive (object value) @@ -2574,8 +3096,81 @@ void WriteVariantType (VariantType variant) { WriteByte ((byte) variant); } + + public void WriteSequencePoints (MethodDebugInformation info) + { + var start_line = -1; + var start_column = -1; + + WriteCompressedUInt32 (info.local_var_token.RID); + + Document previous_document; + if (!info.TryGetUniqueDocument (out previous_document)) + previous_document = null; + + for (int i = 0; i < info.SequencePoints.Count; i++) { + var sequence_point = info.SequencePoints [i]; + + var document = sequence_point.Document; + if (previous_document != document) { + var document_token = metadata.GetDocumentToken (document); + + if (previous_document != null) + WriteCompressedUInt32 (0); + + WriteCompressedUInt32 (document_token.RID); + previous_document = document; + } + + if (i > 0) + WriteCompressedUInt32 ((uint) (sequence_point.Offset - info.SequencePoints [i - 1].Offset)); + else + WriteCompressedUInt32 ((uint) sequence_point.Offset); + + if (sequence_point.IsHidden) { + WriteInt16 (0); + continue; + } + + var delta_lines = sequence_point.EndLine - sequence_point.StartLine; + var delta_columns = sequence_point.EndColumn - sequence_point.StartColumn; + + WriteCompressedUInt32 ((uint) delta_lines); + + if (delta_lines == 0) + WriteCompressedUInt32((uint) delta_columns); + else + WriteCompressedInt32 (delta_columns); + + if (start_line < 0) { + WriteCompressedUInt32 ((uint) sequence_point.StartLine); + WriteCompressedUInt32 ((uint) sequence_point.StartColumn); + } else { + WriteCompressedInt32 (sequence_point.StartLine - start_line); + WriteCompressedInt32 (sequence_point.StartColumn - start_column); + } + + start_line = sequence_point.StartLine; + start_column = sequence_point.StartColumn; + } + } } #endif + static partial class Mixin { + + public static bool TryGetUniqueDocument (this MethodDebugInformation info, out Document document) + { + document = info.SequencePoints [0].Document; + + for (int i = 1; i < info.SequencePoints.Count; i++) { + var sequence_point = info.SequencePoints [i]; + if (sequence_point.Document != document) + return false; + } + + return true; + } + } } diff --git a/Mono.Cecil/MetadataSystem.cs b/Mono.Cecil/MetadataSystem.cs index b5426513e..e9dbf3294 100644 --- a/Mono.Cecil/MetadataSystem.cs +++ b/Mono.Cecil/MetadataSystem.cs @@ -11,6 +11,7 @@ using System; using System.Collections.Generic; +using Mono.Cecil.Cil; using Mono.Cecil.Metadata; namespace Mono.Cecil { @@ -56,6 +57,12 @@ sealed class MetadataSystem { internal Dictionary GenericParameters; internal Dictionary GenericConstraints; + internal Document [] Documents; + internal Dictionary []> LocalScopes; + internal ImportDebugInformation [] ImportScopes; + internal Dictionary StateMachineMethods; + internal Dictionary []> CustomDebugInformations; + static Dictionary> primitive_value_types; static void InitializePrimitives () @@ -142,6 +149,19 @@ public void Clear () if (PInvokes != null) PInvokes.Clear (); if (GenericParameters != null) GenericParameters.Clear (); if (GenericConstraints != null) GenericConstraints.Clear (); + + Documents = new Document [0]; + ImportScopes = new ImportDebugInformation [0]; + if (LocalScopes != null) LocalScopes.Clear (); + if (StateMachineMethods != null) StateMachineMethods.Clear (); + } + + public AssemblyNameReference GetAssemblyNameReference (uint rid) + { + if (rid < 1 || rid > AssemblyReferences.Length) + return null; + + return AssemblyReferences [rid - 1]; } public TypeDefinition GetTypeDefinition (uint rid) @@ -344,6 +364,37 @@ public void RemoveOverrideMapping (MethodDefinition method) Overrides.Remove (method.token.RID); } + public Document GetDocument (uint rid) + { + if (rid < 1 || rid > Documents.Length) + return null; + + return Documents [rid - 1]; + } + + public bool TryGetLocalScopes (MethodDefinition method, out Row [] scopes) + { + return LocalScopes.TryGetValue (method.MetadataToken.RID, out scopes); + } + + public void SetLocalScopes (uint method_rid, Row [] records) + { + LocalScopes [method_rid] = records; + } + + public ImportDebugInformation GetImportScope (uint rid) + { + if (rid < 1 || rid > ImportScopes.Length) + return null; + + return ImportScopes [rid - 1]; + } + + public bool TryGetStateMachineKickOffMethod (MethodDefinition method, out uint rid) + { + return StateMachineMethods.TryGetValue (method.MetadataToken.RID, out rid); + } + public TypeDefinition GetFieldDeclaringType (uint field_rid) { return BinaryRangeSearch (Types, field_rid, true); diff --git a/Mono.Cecil/MethodDefinition.cs b/Mono.Cecil/MethodDefinition.cs index b2664ad5e..c07083e46 100644 --- a/Mono.Cecil/MethodDefinition.cs +++ b/Mono.Cecil/MethodDefinition.cs @@ -15,7 +15,7 @@ namespace Mono.Cecil { - public sealed class MethodDefinition : MethodReference, IMemberDefinition, ISecurityDeclarationProvider { + public sealed class MethodDefinition : MethodReference, IMemberDefinition, ISecurityDeclarationProvider, ICustomDebugInformationProvider { ushort attributes; ushort impl_attributes; @@ -29,6 +29,8 @@ public sealed class MethodDefinition : MethodReference, IMemberDefinition, ISecu Collection overrides; internal MethodBody body; + internal MethodDebugInformation debug_info; + internal Collection custom_infos; public MethodAttributes Attributes { get { return (MethodAttributes) attributes; } @@ -141,6 +143,17 @@ public MethodBody Body { } } + public MethodDebugInformation DebugInformation { + get { + if (debug_info != null) + return debug_info; + + Mixin.Read (Body); + + return debug_info ?? (debug_info = new MethodDebugInformation (this)); + } + } + public bool HasPInvokeInfo { get { if (pinvoke != null) @@ -200,6 +213,22 @@ public override Collection GenericParameters { get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); } } + public bool HasCustomDebugInformations { + get { + Mixin.Read (Body); + + return !custom_infos.IsNullOrEmpty (); + } + } + + public Collection CustomDebugInformations { + get { + Mixin.Read (Body); + + return custom_infos ?? (custom_infos = new Collection ()); + } + } + #region MethodAttributes public bool IsCompilerControlled { diff --git a/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil/ModuleDefinition.cs index 5a9616d98..bd23bce75 100644 --- a/Mono.Cecil/ModuleDefinition.cs +++ b/Mono.Cecil/ModuleDefinition.cs @@ -225,7 +225,7 @@ public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider internal IMetadataResolver metadata_resolver; internal TypeSystem type_system; - readonly MetadataReader reader; + internal readonly MetadataReader reader; readonly string fq_name; internal string runtime_version; @@ -1053,8 +1053,8 @@ public static ModuleDefinition ReadModule (Stream stream, ReaderParameters param throw new ArgumentException (); Mixin.CheckParameters (parameters); - return ModuleReader.CreateModuleFrom ( - ImageReader.ReadImageFrom (stream), + return ModuleReader.CreateModule ( + ImageReader.ReadImage (stream), parameters); } @@ -1192,5 +1192,21 @@ public static string RuntimeVersionString (this TargetRuntime runtime) return "v4.0.30319"; } } + + public static byte [] ReadAll (this Stream self) + { + int read; + var memory = new MemoryStream ((int) self.Length); + var buffer = new byte [1024]; + + while ((read = self.Read (buffer, 0, buffer.Length)) != 0) + memory.Write (buffer, 0, read); + + return memory.GetBuffer (); + } + + public static void Read (object o) + { + } } } diff --git a/Mono.Cecil/TypeParser.cs b/Mono.Cecil/TypeParser.cs index c6069b9f6..3ce5731e4 100644 --- a/Mono.Cecil/TypeParser.cs +++ b/Mono.Cecil/TypeParser.cs @@ -144,13 +144,7 @@ bool TryParse (char chr) static void Add (ref T [] array, T item) { - if (array == null) { - array = new [] { item }; - return; - } - - array = array.Resize (array.Length + 1); - array [array.Length - 1] = item; + array = array.Add (item); } int [] ParseSpecs () diff --git a/Mono/Empty.cs b/Mono/Empty.cs index cef207829..14589cc9e 100644 --- a/Mono/Empty.cs +++ b/Mono/Empty.cs @@ -38,5 +38,17 @@ public static T [] Resize (this T [] self, int length) Array.Resize (ref self, length); return self; } + + public static T [] Add (this T [] self, T item) + { + if (self == null) { + self = new [] { item }; + return self; + } + + self = self.Resize (self.Length + 1); + self [self.Length - 1] = item; + return self; + } } } diff --git a/Test/Mono.Cecil.Tests.csproj b/Test/Mono.Cecil.Tests.csproj index 7fe34cc28..9f019420e 100644 --- a/Test/Mono.Cecil.Tests.csproj +++ b/Test/Mono.Cecil.Tests.csproj @@ -11,6 +11,7 @@ + diff --git a/Test/Mono.Cecil.Tests/BaseTestFixture.cs b/Test/Mono.Cecil.Tests/BaseTestFixture.cs index f782ffcb2..c09fbcba2 100644 --- a/Test/Mono.Cecil.Tests/BaseTestFixture.cs +++ b/Test/Mono.Cecil.Tests/BaseTestFixture.cs @@ -54,7 +54,7 @@ public ModuleDefinition GetResourceModule (string name, ReadingMode mode) internal Image GetResourceImage (string name) { using (var fs = new FileStream (GetAssemblyResourcePath (name, GetType ().Assembly), FileMode.Open, FileAccess.Read)) - return ImageReader.ReadImageFrom (fs); + return ImageReader.ReadImage (fs); } public ModuleDefinition GetCurrentModule () @@ -79,6 +79,19 @@ public static string FindResourcesDirectory (Assembly assembly) return Path.Combine (path, "Resources"); } + public static void AssertCode (string expected, MethodDefinition method) + { + Assert.IsTrue (method.HasBody); + Assert.IsNotNull (method.Body); + + Assert.AreEqual (Normalize (expected), Normalize (Formatter.FormatMethodBody (method))); + } + + static string Normalize (string str) + { + return str.Trim ().Replace ("\r\n", "\n"); + } + public static void TestModule (string file, Action test, bool verify = true, bool readOnly = false, Type symbolReaderProvider = null, Type symbolWriterProvider = null, IAssemblyResolver assemblyResolver = null) { Run (new ModuleTestCase (file, test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver)); @@ -94,7 +107,7 @@ public static void TestIL (string file, Action test, bool veri Run (new ILTestCase (file, test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver)); } - private static void Run (TestCase testCase) + static void Run (TestCase testCase) { var runner = new TestRunner (testCase, TestCaseType.ReadDeferred); runner.RunTest (); @@ -106,10 +119,10 @@ private static void Run (TestCase testCase) return; runner = new TestRunner (testCase, TestCaseType.WriteFromDeferred); - runner.RunTest(); + runner.RunTest (); runner = new TestRunner (testCase, TestCaseType.WriteFromImmediate); - runner.RunTest(); + runner.RunTest (); } } @@ -284,7 +297,7 @@ public void RunTest () if (module == null) return; - test_case.Test(module); + test_case.Test (module); } } diff --git a/Test/Mono.Cecil.Tests/Formatter.cs b/Test/Mono.Cecil.Tests/Formatter.cs index a7e1c8704..7c8c76a6c 100644 --- a/Test/Mono.Cecil.Tests/Formatter.cs +++ b/Test/Mono.Cecil.Tests/Formatter.cs @@ -28,7 +28,7 @@ public static void WriteMethodBody (TextWriter writer, MethodDefinition method) WriteVariables (writer, body); foreach (Instruction instruction in body.Instructions) { - var sequence_point = instruction.SequencePoint; + var sequence_point = body.Method.DebugInformation.GetSequencePoint (instruction); if (sequence_point != null) { writer.Write ('\t'); WriteSequencePoint (writer, sequence_point); @@ -56,11 +56,21 @@ static void WriteVariables (TextWriter writer, MethodBody body) var variable = variables [i]; - writer.Write ("{0} {1}", variable.VariableType, variable); + writer.Write ("{0} {1}", variable.VariableType, GetVariableName (variable, body)); } writer.WriteLine (")"); } + static string GetVariableName (VariableDefinition variable, MethodBody body) + { + foreach (var scope in body.Method.DebugInformation.GetScopes ()) + foreach (var variable_symbol in scope.Variables) + if (variable_symbol.Index == variable.Index) + return variable_symbol.Name; + + return variable.ToString (); + } + static void WriteInstruction (TextWriter writer, Instruction instruction) { writer.Write (FormatLabel (instruction.Offset)); diff --git a/Test/Mono.Cecil.Tests/MethodBodyTests.cs b/Test/Mono.Cecil.Tests/MethodBodyTests.cs index 2fc030ef9..62ae1ccc4 100644 --- a/Test/Mono.Cecil.Tests/MethodBodyTests.cs +++ b/Test/Mono.Cecil.Tests/MethodBodyTests.cs @@ -316,19 +316,6 @@ public void UnattachedMethodBody () Assert.AreEqual (body, method.Body); } - static void AssertCode (string expected, MethodDefinition method) - { - Assert.IsTrue (method.HasBody); - Assert.IsNotNull (method.Body); - - Assert.AreEqual (Normalize (expected), Normalize (Formatter.FormatMethodBody (method))); - } - - static string Normalize (string str) - { - return str.Trim ().Replace ("\r\n", "\n"); - } - [Test] public void AddInstruction () { diff --git a/Test/Mono.Cecil.Tests/PortablePdbTests.cs b/Test/Mono.Cecil.Tests/PortablePdbTests.cs new file mode 100644 index 000000000..14cf1eb32 --- /dev/null +++ b/Test/Mono.Cecil.Tests/PortablePdbTests.cs @@ -0,0 +1,355 @@ +using System; +using System.IO; + +using NUnit.Framework; + +using Mono.Cecil.Cil; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class PortablePdbTests : BaseTestFixture { + + [Test] + public void SequencePoints () + { + TestPortablePdbModule (module => { + var type = module.GetType ("PdbTarget.Program"); + var main = type.GetMethod ("Main"); + + AssertCode (@" + .locals init (System.Int32 a, System.String[] V_1, System.Int32 V_2, System.String arg) + .line 21,21:3,4 'C:\sources\PdbTarget\Program.cs' + IL_0000: nop + .line 22,22:4,11 'C:\sources\PdbTarget\Program.cs' + IL_0001: nop + .line 22,22:24,28 'C:\sources\PdbTarget\Program.cs' + IL_0002: ldarg.0 + IL_0003: stloc.1 + IL_0004: ldc.i4.0 + IL_0005: stloc.2 + .line 16707566,0:16707566,0 'C:\sources\PdbTarget\Program.cs' + IL_0006: br.s IL_0017 + .line 22,22:13,20 'C:\sources\PdbTarget\Program.cs' + IL_0008: ldloc.1 + IL_0009: ldloc.2 + IL_000a: ldelem.ref + IL_000b: stloc.3 + .line 23,23:5,20 'C:\sources\PdbTarget\Program.cs' + IL_000c: ldloc.3 + IL_000d: call System.Void System.Console::WriteLine(System.String) + IL_0012: nop + .line 16707566,0:16707566,0 'C:\sources\PdbTarget\Program.cs' + IL_0013: ldloc.2 + IL_0014: ldc.i4.1 + IL_0015: add + IL_0016: stloc.2 + .line 22,22:21,23 'C:\sources\PdbTarget\Program.cs' + IL_0017: ldloc.2 + IL_0018: ldloc.1 + IL_0019: ldlen + IL_001a: conv.i4 + IL_001b: blt.s IL_0008 + .line 25,25:4,22 'C:\sources\PdbTarget\Program.cs' + IL_001d: ldc.i4.1 + IL_001e: ldc.i4.2 + IL_001f: call System.Int32 System.Math::Min(System.Int32,System.Int32) + IL_0024: stloc.0 + .line 26,26:3,4 'C:\sources\PdbTarget\Program.cs' + IL_0025: ret +", main); + }); + } + + [Test] + public void SequencePointsMultipleDocument () + { + TestPortablePdbModule (module => { + var type = module.GetType ("PdbTarget.B"); + var main = type.GetMethod (".ctor"); + + AssertCode (@" + .locals () + .line 7,7:3,25 'C:\sources\PdbTarget\B.cs' + IL_0000: ldarg.0 + IL_0001: ldstr """" + IL_0006: stfld System.String PdbTarget.B::s + .line 110,110:3,21 'C:\sources\PdbTarget\Program.cs' + IL_000b: ldarg.0 + IL_000c: ldc.i4.2 + IL_000d: stfld System.Int32 PdbTarget.B::a + .line 111,111:3,21 'C:\sources\PdbTarget\Program.cs' + IL_0012: ldarg.0 + IL_0013: ldc.i4.3 + IL_0014: stfld System.Int32 PdbTarget.B::b + .line 9,9:3,13 'C:\sources\PdbTarget\B.cs' + IL_0019: ldarg.0 + IL_001a: call System.Void System.Object::.ctor() + IL_001f: nop + .line 10,10:3,4 'C:\sources\PdbTarget\B.cs' + IL_0020: nop + .line 11,11:4,19 'C:\sources\PdbTarget\B.cs' + IL_0021: ldstr ""B"" + IL_0026: call System.Void System.Console::WriteLine(System.String) + IL_002b: nop + .line 12,12:3,4 'C:\sources\PdbTarget\B.cs' + IL_002c: ret +", main); + }); + } + + [Test] + public void LocalVariables () + { + TestPortablePdbModule (module => { + var type = module.GetType ("PdbTarget.Program"); + var method = type.GetMethod ("Bar"); + var debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + Assert.IsTrue (debug_info.Scope.HasScopes); + Assert.AreEqual (2, debug_info.Scope.Scopes.Count); + + var scope = debug_info.Scope.Scopes [0]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasVariables); + Assert.AreEqual (1, scope.Variables.Count); + + var variable = scope.Variables [0]; + + Assert.AreEqual ("s", variable.Name); + Assert.IsFalse (variable.IsDebuggerHidden); + Assert.AreEqual (2, variable.Index); + + scope = debug_info.Scope.Scopes [1]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasVariables); + Assert.AreEqual (1, scope.Variables.Count); + + variable = scope.Variables [0]; + + Assert.AreEqual ("s", variable.Name); + Assert.IsFalse (variable.IsDebuggerHidden); + Assert.AreEqual (3, variable.Index); + + Assert.IsTrue (scope.HasScopes); + Assert.AreEqual (1, scope.Scopes.Count); + + scope = scope.Scopes [0]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasVariables); + Assert.AreEqual (1, scope.Variables.Count); + + variable = scope.Variables [0]; + + Assert.AreEqual ("u", variable.Name); + Assert.IsFalse (variable.IsDebuggerHidden); + Assert.AreEqual (5, variable.Index); + }); + } + + [Test] + public void LocalConstants () + { + TestPortablePdbModule (module => { + var type = module.GetType ("PdbTarget.Program"); + var method = type.GetMethod ("Bar"); + var debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + Assert.IsTrue (debug_info.Scope.HasScopes); + Assert.AreEqual (2, debug_info.Scope.Scopes.Count); + + var scope = debug_info.Scope.Scopes [1]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasConstants); + Assert.AreEqual (2, scope.Constants.Count); + + var constant = scope.Constants [0]; + + Assert.AreEqual ("b", constant.Name); + Assert.AreEqual (12, constant.Value); + Assert.AreEqual (MetadataType.Int32, constant.ConstantType.MetadataType); + + constant = scope.Constants [1]; + Assert.AreEqual ("c", constant.Name); + Assert.AreEqual ((decimal) 74, constant.Value); + Assert.AreEqual (MetadataType.ValueType, constant.ConstantType.MetadataType); + + method = type.GetMethod ("Foo"); + debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + Assert.IsTrue (debug_info.Scope.HasConstants); + Assert.AreEqual (4, debug_info.Scope.Constants.Count); + + constant = debug_info.Scope.Constants [0]; + Assert.AreEqual ("s", constant.Name); + Assert.AreEqual ("const string", constant.Value); + Assert.AreEqual (MetadataType.String, constant.ConstantType.MetadataType); + + constant = debug_info.Scope.Constants [1]; + Assert.AreEqual ("f", constant.Name); + Assert.AreEqual (1, constant.Value); + Assert.AreEqual (MetadataType.Int32, constant.ConstantType.MetadataType); + + constant = debug_info.Scope.Constants [2]; + Assert.AreEqual ("o", constant.Name); + Assert.AreEqual (null, constant.Value); + Assert.AreEqual (MetadataType.Object, constant.ConstantType.MetadataType); + + constant = debug_info.Scope.Constants [3]; + Assert.AreEqual ("u", constant.Name); + Assert.AreEqual (null, constant.Value); + Assert.AreEqual (MetadataType.String, constant.ConstantType.MetadataType); + }); + } + + [Test] + public void ImportScope () + { + TestPortablePdbModule (module => { + var type = module.GetType ("PdbTarget.Program"); + var method = type.GetMethod ("Bar"); + var debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + + var import = debug_info.Scope.Import; + Assert.IsNotNull (import); + + Assert.IsFalse (import.HasTargets); + Assert.IsNotNull (import.Parent); + + import = import.Parent; + + Assert.IsTrue (import.HasTargets); + Assert.AreEqual (9, import.Targets.Count); + var target = import.Targets [0]; + + Assert.AreEqual (ImportTargetKind.ImportAlias, target.Kind); + Assert.AreEqual ("XML", target.Alias); + + target = import.Targets [1]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual ("System", target.Namespace); + + target = import.Targets [2]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual ("System.Collections.Generic", target.Namespace); + + target = import.Targets [3]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual ("System.IO", target.Namespace); + + target = import.Targets [4]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual ("System.Threading.Tasks", target.Namespace); + + target = import.Targets [5]; + + Assert.AreEqual (ImportTargetKind.ImportNamespaceInAssembly, target.Kind); + Assert.AreEqual ("System.Xml.Resolvers", target.Namespace); + Assert.AreEqual ("System.Xml", target.AssemblyReference.Name); + + + target = import.Targets [6]; + + Assert.AreEqual (ImportTargetKind.ImportType, target.Kind); + Assert.AreEqual ("System.Console", target.Type.FullName); + + target = import.Targets [7]; + + Assert.AreEqual (ImportTargetKind.ImportType, target.Kind); + Assert.AreEqual ("System.Math", target.Type.FullName); + + target = import.Targets [8]; + + Assert.AreEqual (ImportTargetKind.DefineTypeAlias, target.Kind); + Assert.AreEqual ("Foo", target.Alias); + Assert.AreEqual ("System.Xml.XmlDocumentType", target.Type.FullName); + + Assert.IsNotNull (import.Parent); + + import = import.Parent; + + Assert.IsTrue (import.HasTargets); + Assert.AreEqual (1, import.Targets.Count); + Assert.IsNull (import.Parent); + + target = import.Targets [0]; + + Assert.AreEqual (ImportTargetKind.DefineAssemblyAlias, target.Kind); + Assert.AreEqual ("XML", target.Alias); + Assert.AreEqual ("System.Xml", target.AssemblyReference.Name); + }); + } + + [Test] + public void StateMachineKickOff () + { + TestPortablePdbModule (module => { + var state_machine = module.GetType ("PdbTarget.Program/d__7"); + var main = state_machine.GetMethod ("MoveNext"); + var symbol = main.DebugInformation; + + Assert.IsNotNull (symbol); + Assert.IsNotNull (symbol.StateMachineKickOffMethod); + Assert.AreEqual ("System.Threading.Tasks.Task PdbTarget.Program::Baz(System.IO.StreamReader)", symbol.StateMachineKickOffMethod.FullName); + }); + } + + [Test] + public void StateMachineCustomDebugInformation () + { + TestPortablePdbModule (module => { + var state_machine = module.GetType ("PdbTarget.Program/d__7"); + var move_next = state_machine.GetMethod ("MoveNext"); + + Assert.IsTrue (move_next.HasCustomDebugInformations); + Assert.AreEqual (2, move_next.CustomDebugInformations.Count); + + var state_machine_scope = move_next.CustomDebugInformations [0] as StateMachineScopeDebugInformation; + Assert.IsNotNull (state_machine_scope); + Assert.AreEqual (0, state_machine_scope.Start.Offset); + Assert.IsTrue (state_machine_scope.End.IsEndOfMethod); + + var async_body = move_next.CustomDebugInformations [1] as AsyncMethodBodyDebugInformation; + Assert.IsNotNull (async_body); + Assert.AreEqual (-1, async_body.CatchHandler.Offset); + + Assert.AreEqual (2, async_body.Yields.Count); + Assert.AreEqual (61, async_body.Yields [0].Offset); + Assert.AreEqual (221, async_body.Yields [1].Offset); + + Assert.AreEqual (2, async_body.Resumes.Count); + Assert.AreEqual (91, async_body.Resumes [0].Offset); + Assert.AreEqual (252, async_body.Resumes [1].Offset); + + Assert.AreEqual (move_next, async_body.MoveNextMethod); + }); + } + + void TestPortablePdbModule (Action test) + { + TestModule ("PdbTarget.exe", test, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + TestModule ("EmbeddedPdbTarget.exe", test, verify: !Platform.OnMono); + } + + [Test] + public void RoundTripCecilPortablePdb () + { + TestModule ("cecil.dll", module => { + Assert.IsTrue (module.HasSymbols); + }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + } +} diff --git a/Test/Mono.Cecil.Tests/VariableTests.cs b/Test/Mono.Cecil.Tests/VariableTests.cs index 9f6c54c67..577e56f5a 100644 --- a/Test/Mono.Cecil.Tests/VariableTests.cs +++ b/Test/Mono.Cecil.Tests/VariableTests.cs @@ -18,8 +18,8 @@ public void AddVariableIndex () var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); var body = new MethodBody (method); - var x = new VariableDefinition ("x", object_ref); - var y = new VariableDefinition ("y", object_ref); + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); body.Variables.Add (x); body.Variables.Add (y); @@ -35,9 +35,9 @@ public void RemoveAtVariableIndex () var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); var body = new MethodBody (method); - var x = new VariableDefinition ("x", object_ref); - var y = new VariableDefinition ("y", object_ref); - var z = new VariableDefinition ("z", object_ref); + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); + var z = new VariableDefinition (object_ref); body.Variables.Add (x); body.Variables.Add (y); @@ -61,9 +61,9 @@ public void RemoveVariableIndex () var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); var body = new MethodBody (method); - var x = new VariableDefinition ("x", object_ref); - var y = new VariableDefinition ("y", object_ref); - var z = new VariableDefinition ("z", object_ref); + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); + var z = new VariableDefinition (object_ref); body.Variables.Add (x); body.Variables.Add (y); @@ -87,9 +87,9 @@ public void InsertVariableIndex () var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); var body = new MethodBody (method); - var x = new VariableDefinition ("x", object_ref); - var y = new VariableDefinition ("y", object_ref); - var z = new VariableDefinition ("z", object_ref); + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); + var z = new VariableDefinition (object_ref); body.Variables.Add (x); body.Variables.Add (z); diff --git a/Test/Resources/assemblies/EmbeddedPdbTarget.exe b/Test/Resources/assemblies/EmbeddedPdbTarget.exe new file mode 100644 index 0000000000000000000000000000000000000000..8769bc89e17014bc87b1048e4a00f957800342f3 GIT binary patch literal 11264 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 Y4DoxEo$lX#+~4+lwEh1k|LZ;Q-;t39+yDRo literal 0 HcmV?d00001 diff --git a/Test/Resources/assemblies/PdbTarget.exe b/Test/Resources/assemblies/PdbTarget.exe new file mode 100644 index 0000000000000000000000000000000000000000..e53b203cf61bc26ed6c17e9f8acb177be6f271ac GIT binary patch literal 10240 zcmeHNeQ;dWbwBs*?%Su8EVQdngRmCari)~)_2m!D+DO)i5m>gcWE;CC>!;l(Y4Ps9 z^?SR*LI}hFZ9EAShh_pTrR6IVCT2#QckVqO_uO;Oz4zRY_2|L-$U{V4e82e((eubT^-1{YU=i%aOr|i=;izR>31HH;J`}j4VSHt&57tL5BW*&EZKcEbSl8wF%2FTE_A*o!KSuvK zv26;$0jP6d9g&dul3Q8k^Q31L3srLq0A8hO0akdGl?#|*UM12(6d1B%9q zrAPaz$BtemziGQvD_>25P?G^2_4S{z~LO`jP&7+{qZ-74YVt|E>07}cR zC97QriwR~Uvo-;+@Mad7XUx2k=?DhE8CGfQE@KJiEnsp4lt!tjF>q#UQ7PKHmHFrD zD`2dvzX61fuQ>f8rA}JW5ICbL5k$HGy{)#%e!_`#>XZ`&E!TcW!@4S0Q$5SKty1Q> z`L>Jgt;lZacF-?#i|jL=y93DKFxN*d=X#oyc^(5f8aIYQzJx0#k?r-0*`8_mB$~-R<6VWGN!ioSE zMr06q$AHqXHXv7w;$LWjjIu(JO9d;(6TzZwr*}3(y)w_tO66A0&ed14AM4$k&@~KQ zRUzRrv<0}ti$URR0Sna&|4Pz4BjyfBH#n>P%D*f#4>8a&uhtjxIra@HjYa!{zU2n` zN(O#S_K+>B^K%JWFuGKQ>2Mc< z&FbxGa}qcw45`@P@@Qp6HIV-iJ%k>@B*I#fn+>83lL+%x;^>9s7morg3mx)f8O#L9 z=XHXnN<5-@FUzu)4?WMRD&6R1_^fhFy@-B-P@&QpCFoP>M;?aHNI2-_a*c#nNO+y3 zzotBZy5ErSYmzeMx!#~YBk*|xieD!9$9`2`c?XG-ykFpO8OrQF5fOS{7kU6 zoy0Ka`^Z}jUvl|7XseoRXb8}k)cufuLt3>UZTM^G4AHRf+rAL}TxIyrC|A>I*bt&~ zpj1=6vJSPLm3>?d%_`j~?HnSu`6*~)|8nHzF<@`k&_9vw?=NBRdl~a$R6GdUJcj*< zK$Q}EL1ICwqdUQSMPe(d5p{3!zbOR$D|G^X0N6nP=zk0FM&G}P>lYpRjKbU#S~Xyw z;PL~)h7a!t6!f8Q9_0@J1#IdE_fBHThvP~*^(vK$La(~m0bi@)rL!((`R;-ruvZ|R zpr^FU6(8kY?C-oCib?~m4)3_POYzfgi8<|Qbc4fd%Bro3MpGpoTYi_s-W9{pQ9-Y` z*yGyez)r4aop+E4Z&c8$5_`9zQ|ktH+QGyE#W@;vHxV4K#kmUqQf z>P}$gmQ_%n%X?g7Eg$39#ge}gdw}t*s6p)DvEh~ZAvSnHuVB^)_?;y=3Aznjfl*I6O&-`)6*BMvuAmVlA#~^C$fef#Sm|RIQ;yLtP*$ZfcoiS-=OxhVEo(-pjCT@>0@m=q;;*@BF%=>hu?*+h<@RdeQh>}sP{5~a0wKM{F3G9v1YB~zo zPG1DfH0wDm-a~m&!m|>R!j!OteG(p)@FfYqfZ6vIdYU$gt3+JP2ruR+ z(NFxFFk36M7}onm*mo4nOCM%x6MEvs{@MY!iq->$F+aVy&-MVWp$&kS(kv;LcP(5y1)yvf+kl$}Qw+m?yPhf`V9orA(` zzNedFsF2~-QRLRUX}FM090oSU)E`x|1I%03u)~Af!*#R?? zOB;D3NvvwbUcyJRv*r<_+_g~I6OS7uSJTK~%FdZKyPftFviVfTn3&5M*XY?KC_9Wi zW5br2aVZ1nmkG{(3y$SZ(1`5DcwWyNqk3Y7N#jO-8E%&|hmPee!?xidR!ui#(t~CK zL!XsRk(?Au&a|M-_4kscQKx9o034M!(5bF?TsBggI5aqy)ibF?e;!B9$pVDfEvd9& z$w5J_8aBcoeKmRJ+Ig@GT&%b9VrSaBK4ZYl%~`4G znG3QqIXyeKRL7mI+$P$YOr=x#GVWM%((y~wIEHzw-(qHu>@lW_lgX_db-RyC2|0HY z8rAbNav|+BvePK0+{%*1v4{qZL@J}Fi>fez2_52>OP55WsVwvWY)3G%=62_J*x|-v z6&T{i2-;=l#|ycfX<9H3%)48_Z>d)%{|Vt}f~!OmGP6sK z4yN?!tZC;{37f;rby@S~>|j1=7mX@T0_+rqW#+~WYc`cI&SMt?M~UyOE6f?}2@pSj ze1_9HF1Zffag{^CLM>@`;yIK=c}PlRgw&(ar4U)7mpQO#KDrd$V;~yOVhz*o$(yk4 zP-)&5rOGOnJPvPhO(V|%9)&_W&r{AV4P|FjmYL;4xbGX?AzI@)meZ-F@vs zHHxFjwtR}%Z&8eZSKKr|OL@6yY+H9co^Uo>tP|bJ)2KOX?BXYN?D+BsBgnIzXk`Lt z;4Dsxd7Q);T8IQ$nwBC94{RCu-rK8pJa^w+M<01uJWAfM5Sj-Ee;*3LAfwd`6vjh) z8D6S@ulVaji}#3HRKQ^tgl4rqbR+PJFu5FGm_m!kRj#-AAP$Y9+VA&jmsV@lK2kJI zLxmc#iu`Ux#&xBZaQlG?nqSo*q-d&N3DpG)IL-wNeq3@z%_=;wiBKIH4rQwRzUJmj zo9jahqPf{8Gd8gn$2eFUTzs*Dl+fa-;Nss_*O520_IqkL(Tl z4|xbG=$qz;_8OoKe!o^9T>J}BT^*`ZoKk4<5luSpXQG<5AY*5;R4u8FOrTRy*aJ1I zL?BSCR|ofNj-MaVp1bAHzLmXak84j~9lt&JcLf{|9#YL6Nk!8htrg9YSA;dg03 zklR}310M$9(&~m9p|F=$VLTnEE2~IBckyN*LYdG}6q{MLrr8_eNf4oCjj!XJR`F}d zgwn9z(sR4aY-tbR$pwT;XL9m#M*{-aCnVWvE;zphiqSD9H-mf&hpQR7o-|@Ix0sMkM zVJ@AYiof?cocMrg4IRUQABP-y12T+gGR<$k_%(Pfh5Kab_uzNM1B!gV4-+lo*9;m% zzP#toEAQqD&{^&i!k{?vGv~3Kwf+Od(EIxEynwuzVjld^NBi*R69*ikJt&RfEn*k& z5x`;R*Lr%<`-^i<%y4uS;|G4Pk_lU8SwwMYgOaunw|xtGQuu8H*It|krf^2!w1&9W z1h~39Go+E{A;%{OCq3>oKp7&-Qb#^z(8ZpY--8eZ5)M=|^vD**6}=Ie6l;>b*Tc z^dH6L0Dt}BZ@w41`dB6%=9>lXty^1h8fXn0*@T(Ijb&@=-ihIk&8=ZPxnz@i+RPeT zTjvbB_3CXa0xJSB-F+AdLq*o!+FG!(TkOOPo-OPSJjpmW){cak*`nK-=xkSOIHPA% zQ-+-{o-Aa0P!(i+A?4-6Qc>(AxVsf4^~NA+B;b-kk@Zx!r3 zUz9Lc9@@4I+!fHKi-TerM+>miNRC;lSv;Ri8}{ea+EdgTMq1K?O*B#9w}G9; ztdS0<8E$RWZRhFEY7G}s{RtdU;KnIEZ5wW}X)u%>AG`enAq)|Z?Bf!O-u2yMe) V|6daVQx)nq^O@oI>37Zp{|k_hJJ0|C literal 0 HcmV?d00001 diff --git a/Test/Resources/assemblies/PdbTarget.pdb b/Test/Resources/assemblies/PdbTarget.pdb new file mode 100644 index 0000000000000000000000000000000000000000..3c6fc6beee2f2cc2dc30509fb7b7665ae7092c2c GIT binary patch literal 1692 zcmZWqYiL|W6h3qA?%h{5$!>P@($ut#vBq|d+G>r6%_eP{(vW9uAi=uXZntYUx#r$& zd?3j}6!o9Q`bPv?6^Z^6Ef!H*u(epBAZift@k>D}sPu;sEAcyX@5+L+oVn*UbG~zC z=4^U=Us{nO88x7h{&f4o9jR`uAd{W~Qvz)sIXok}-$7d#@*+{Q0TSDI$u7+09kF*q z=M&w5aoP@kMEHRNgZ=nEE&ia*>7pf@z4Y_SwdeDzL+>7X^u!+viSx$gXAWX(^WaUd zMMAZtQT4#j1hs$~K_O4xhp(XC01A3M){>C;L_D2fK}f9^n+$y2glXMX&;@Om{p&zs zki_(Z#4!Ns1h*Al`|%yq-g(Sny$@55VtUNuuYzyUp_sZVA>n)Xe>}GP-(Whe?Fwis z=dlf53=|c)(~}t*$ystVV3!p#1i!CJPC)i+Su!Eo1rk|&Ds>cDelgf?@$4ot7QP;2 z!WPgKAi587pi2G(au9OFvkRVZl^lf}t&%^7oUD>hy0A5RLnCtQ%^HoNXFoMym8+N9 zxD}DSqp**t06n7W$W{$hQU-mc{PZn$m70Z6J6ZRezK=;{vW8VjZiZiycVcehNj;xZ zK6;K%v5&4}_R~+YFhetxr6ZKF^Hd~@96AoI9=|p=uRrv5{m`?2T7%i;?GLZbj6U#b z;LF$x<8*%bbv}I|dvW>NdtVQn?f77#cVKa4!<%o-URo>d{dnf+hYxoDIDfJ0pNX4) zY2Eco*I&a;^)_Hl4(&Hg#cb^6zMg<%9k;VNCxj!rj3aw_kOgj zrao)1cJBD$WbLKPp}RWY2#?rS-p!Bwp6g@oYX*WE@v0A zABI6u$5}tZ;wwM~rIaYBYXFJ9o%WCy2Ren*GUsmNas(g;Q zylU(=MnmPRL$?E=N*am+%nIkW1<#j(?U)b9=J5`F#7pfa#mz%Oftkd4sIBmi)&O@@ zT%m2L&Eml3aAYNF*RxFp$ax9`5rE3?s2jO~4}ns}=#=;lQCW1lHd@_S6zh0!r9jQ|Qd3wl);qJIHT%Fy%x literal 0 HcmV?d00001 diff --git a/Test/Resources/assemblies/cecil.dll b/Test/Resources/assemblies/cecil.dll new file mode 100644 index 0000000000000000000000000000000000000000..b311beebf9d62e4a8aa188c17b06f71ad94af324 GIT binary patch literal 344064 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

T;9OJSC{deuhI-yjaGvMQYaMhJT- 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

X1FYL4 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 literal 0 HcmV?d00001 diff --git a/rocks/Test/Mono.Cecil.Rocks.Tests.csproj b/rocks/Test/Mono.Cecil.Rocks.Tests.csproj index 808c2a1b5..4daae6445 100644 --- a/rocks/Test/Mono.Cecil.Rocks.Tests.csproj +++ b/rocks/Test/Mono.Cecil.Rocks.Tests.csproj @@ -32,6 +32,9 @@ + + + \ No newline at end of file diff --git a/rocks/Test/Mono.Cecil.Tests/DocCommentIdTests.cs b/rocks/Test/Mono.Cecil.Tests/DocCommentIdTests.cs index de45a2f55..48c0fabe5 100644 --- a/rocks/Test/Mono.Cecil.Tests/DocCommentIdTests.cs +++ b/rocks/Test/Mono.Cecil.Tests/DocCommentIdTests.cs @@ -70,13 +70,15 @@ public X(int i) { } ///

/// ID string generated is "E:N.X.d". /// +#pragma warning disable 67 public event D d; +#pragma warning restore 67 - /// - /// ID string generated is "P:N.X.Item(System.String)". - /// - public int this[string s] { get { return 1; } } + /// + /// ID string generated is "P:N.X.Item(System.String)". + /// + public int this[string s] { get { return 1; } } /// diff --git a/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs b/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs index 05ab3fb94..fa7226066 100644 --- a/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs +++ b/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs @@ -57,30 +57,30 @@ public bool ProcessDebugHeader (ImageDebugDirectory directory, byte [] header) return symbol_file.Guid == module.Mvid; } - public void Read (MethodBody body, InstructionMapper mapper) + public MethodDebugInformation Read (MethodDefinition method) { - var method_token = body.Method.MetadataToken; + var method_token = method.MetadataToken; var entry = symbol_file.GetMethodByToken (method_token.ToInt32 ()); if (entry == null) - return; + return null; - var scopes = ReadScopes (entry, body, mapper); - ReadLineNumbers (entry, mapper); - ReadLocalVariables (entry, body, scopes); + var info = new MethodDebugInformation (method); + + var scopes = ReadScopes (entry, info); + ReadLineNumbers (entry, info); + ReadLocalVariables (entry, scopes); + + return info; } - static void ReadLocalVariables (MethodEntry entry, MethodBody body, Scope [] scopes) + static void ReadLocalVariables (MethodEntry entry, ScopeDebugInformation [] scopes) { var locals = entry.GetLocals (); foreach (var local in locals) { - if (local.Index < 0 || local.Index >= body.Variables.Count) // Mono 2.6 emits wrong local infos for iterators - continue; - - var variable = body.Variables [local.Index]; - variable.Name = local.Name; + var variable = new VariableDebugInformation (local.Index, local.Name); - var index = local.BlockIndex; + var index = local.BlockIndex - 1; if (index < 0 || index >= scopes.Length) continue; @@ -92,20 +92,22 @@ static void ReadLocalVariables (MethodEntry entry, MethodBody body, Scope [] sco } } - void ReadLineNumbers (MethodEntry entry, InstructionMapper mapper) + void ReadLineNumbers (MethodEntry entry, MethodDebugInformation info) { Document document = null; var table = entry.GetLineNumberTable (); - foreach (var line in table.LineNumbers) { - var instruction = mapper (line.Offset); - if (instruction == null) - continue; + info.sequence_points = new Collection (table.LineNumbers.Length); + for (var i = 0; i < table.LineNumbers.Length; i++) { + var line = table.LineNumbers [i]; if (document == null) document = GetDocument (entry.CompileUnit.SourceFile); - instruction.SequencePoint = LineToSequencePoint (line, entry, document); + if (i > 0 && table.LineNumbers [i - 1].Offset == line.Offset) + continue; + + info.sequence_points.Add (LineToSequencePoint (line, entry, document)); } } @@ -123,35 +125,37 @@ Document GetDocument (SourceFileEntry file) return document; } - static Scope [] ReadScopes (MethodEntry entry, MethodBody body, InstructionMapper mapper) + static ScopeDebugInformation [] ReadScopes (MethodEntry entry, MethodDebugInformation info) { var blocks = entry.GetCodeBlocks (); - var scopes = new Scope [blocks.Length]; + var scopes = new ScopeDebugInformation [blocks.Length]; foreach (var block in blocks) { if (block.BlockType != CodeBlockEntry.Type.Lexical) continue; - var scope = new Scope (); - scope.Start = mapper (block.StartOffset); - scope.End = mapper (block.EndOffset); + var scope = new ScopeDebugInformation (); + scope.Start = new InstructionOffset (block.StartOffset); + scope.End = new InstructionOffset (block.EndOffset); scopes [block.Index] = scope; - if (body.Scope == null) - body.Scope = scope; + if (info.scope == null) { + info.scope = scope; + continue; + } - if (!AddScope (body.Scope, scope)) - body.Scope = scope; + if (!AddScope (info.scope.Scopes, scope)) + info.scope.Scopes.Add (scope); } return scopes; } - static bool AddScope (Scope provider, Scope scope) + static bool AddScope (Collection scopes, ScopeDebugInformation scope) { - foreach (var sub_scope in provider.Scopes) { - if (AddScope (sub_scope, scope)) + foreach (var sub_scope in scopes) { + if (sub_scope.HasScopes && AddScope (sub_scope.Scopes, scope)) return true; if (scope.Start.Offset >= sub_scope.Start.Offset && scope.End.Offset <= sub_scope.End.Offset) { @@ -163,46 +167,9 @@ static bool AddScope (Scope provider, Scope scope) return false; } - public void Read (MethodSymbols symbols) - { - var entry = symbol_file.GetMethodByToken (symbols.MethodToken.ToInt32 ()); - if (entry == null) - return; - - ReadLineNumbers (entry, symbols); - ReadLocalVariables (entry, symbols); - } - - void ReadLineNumbers (MethodEntry entry, MethodSymbols symbols) - { - var table = entry.GetLineNumberTable (); - var lines = table.LineNumbers; - - var instructions = symbols.instructions = new Collection (lines.Length); - - for (int i = 0; i < lines.Length; i++) { - var line = lines [i]; - - instructions.Add (new InstructionSymbol ( - line.Offset, - LineToSequencePoint (line, entry, GetDocument (entry.CompileUnit.SourceFile)))); - } - } - - static void ReadLocalVariables (MethodEntry entry, MethodSymbols symbols) - { - foreach (var local in entry.GetLocals ()) { - if (local.Index < 0 || local.Index >= symbols.Variables.Count) // Mono 2.6 emits wrong local infos for iterators - continue; - - var variable = symbols.Variables [local.Index]; - variable.Name = local.Name; - } - } - static SequencePoint LineToSequencePoint (LineNumberEntry line, MethodEntry entry, Document document) { - return new SequencePoint (document) { + return new SequencePoint (line.Offset, document) { StartLine = line.Row, EndLine = line.EndRow, StartColumn = line.Column, diff --git a/symbols/mdb/Mono.Cecil.Mdb/MdbWriter.cs b/symbols/mdb/Mono.Cecil.Mdb/MdbWriter.cs index 66c5b34ba..1963e4371 100644 --- a/symbols/mdb/Mono.Cecil.Mdb/MdbWriter.cs +++ b/symbols/mdb/Mono.Cecil.Mdb/MdbWriter.cs @@ -45,16 +45,6 @@ public MdbWriter (Guid mvid, string assembly) this.source_files = new Dictionary (); } - static Collection GetInstructions (MethodBody body) - { - var instructions = new Collection (); - foreach (var instruction in body.Instructions) - if (instruction.SequencePoint != null) - instructions.Add (instruction); - - return instructions; - } - SourceFile GetSourceFile (Document document) { var url = document.Url; @@ -71,16 +61,15 @@ SourceFile GetSourceFile (Document document) return source_file; } - void Populate (Collection instructions, int [] offsets, + void Populate (Collection sequencePoints, int [] offsets, int [] startRows, int [] endRows, int [] startCols, int [] endCols, out SourceFile file) { SourceFile source_file = null; - for (int i = 0; i < instructions.Count; i++) { - var instruction = instructions [i]; - offsets [i] = instruction.Offset; + for (int i = 0; i < sequencePoints.Count; i++) { + var sequence_point = sequencePoints [i]; + offsets [i] = sequence_point.Offset; - var sequence_point = instruction.SequencePoint; if (source_file == null) source_file = GetSourceFile (sequence_point.Document); @@ -93,12 +82,12 @@ void Populate (Collection instructions, int [] offsets, file = source_file; } - public void Write (MethodBody body) + public void Write (MethodDebugInformation info) { - var method = new SourceMethod (body.Method); + var method = new SourceMethod (info.method); - var instructions = GetInstructions (body); - int count = instructions.Count; + var sequence_points = info.SequencePoints; + int count = sequence_points.Count; if (count == 0) return; @@ -109,7 +98,7 @@ public void Write (MethodBody body) var end_cols = new int [count]; SourceFile file; - Populate (instructions, offsets, start_rows, end_rows, start_cols, end_cols, out file); + Populate (sequence_points, offsets, start_rows, end_rows, start_cols, end_cols, out file); var builder = writer.OpenMethod (file.CompilationUnit, 0, method); @@ -124,37 +113,41 @@ public void Write (MethodBody body) false); } - if (body.Scope != null && body.Scope.HasScopes) - WriteScope (body.Scope, true); - else - if (body.HasVariables) - AddVariables (body.Variables); + if (info.scope != null) + WriteScope (info.scope); writer.CloseMethod (); } - private void WriteScope (Scope scope, bool root) + void WriteScope (ScopeDebugInformation scope) { - if (scope.Start.Offset == scope.End.Offset) return; - writer.OpenScope (scope.Start.Offset); + if (scope.Start.Offset == scope.End.Offset) + return; + writer.OpenScope(scope.Start.Offset); - if (scope.HasVariables) - { - foreach (var el in scope.Variables) - { - if (!String.IsNullOrEmpty (el.Name)) - writer.DefineLocalVariable (el.Index, el.Name); - } - } + WriteScopeVariables (scope); if (scope.HasScopes) - { - foreach (var el in scope.Scopes) - WriteScope (el, false); - } + WriteScopes (scope.Scopes); + + writer.CloseScope(scope.End.Offset); + } - writer.CloseScope (scope.End.Offset + scope.End.GetSize()); + void WriteScopes (Collection scopes) + { + for (int i = 0; i < scopes.Count; i++) + WriteScope (scopes [i]); + } + + void WriteScopeVariables (ScopeDebugInformation scope) + { + if (!scope.HasVariables) + return; + + foreach (var variable in scope.variables) + if (!string.IsNullOrEmpty (variable.Name)) + writer.DefineLocalVariable (variable.Index, variable.Name); } readonly static byte [] empty_header = new byte [0]; @@ -166,7 +159,7 @@ public bool GetDebugHeader (out ImageDebugDirectory directory, out byte [] heade return false; } - void AddVariables (IList variables) + void AddVariables (IList variables) { for (int i = 0; i < variables.Count; i++) { var variable = variables [i]; @@ -174,34 +167,6 @@ void AddVariables (IList variables) } } - public void Write (MethodSymbols symbols) - { - var method = new SourceMethodSymbol (symbols); - - var file = GetSourceFile (symbols.Instructions [0].SequencePoint.Document); - var builder = writer.OpenMethod (file.CompilationUnit, 0, method); - var count = symbols.Instructions.Count; - - for (int i = 0; i < count; i++) { - var instruction = symbols.Instructions [i]; - var sequence_point = instruction.SequencePoint; - - builder.MarkSequencePoint ( - instruction.Offset, - GetSourceFile (sequence_point.Document).CompilationUnit.SourceFile, - sequence_point.StartLine, - sequence_point.StartColumn, - sequence_point.EndLine, - sequence_point.EndColumn, - false); - } - - if (symbols.HasVariables) - AddVariables (symbols.Variables); - - writer.CloseMethod (); - } - public void Dispose () { writer.WriteSymbolFile (mvid); @@ -227,26 +192,6 @@ public SourceFile (CompileUnitEntry comp_unit, SourceFileEntry entry) } } - class SourceMethodSymbol : IMethodDef { - - readonly string name; - readonly int token; - - public string Name { - get { return name;} - } - - public int Token { - get { return token; } - } - - public SourceMethodSymbol (MethodSymbols symbols) - { - name = symbols.MethodName; - token = symbols.MethodToken.ToInt32 (); - } - } - class SourceMethod : IMethodDef { readonly MethodDefinition method; diff --git a/symbols/mdb/Test/Mono.Cecil.Tests/MdbTests.cs b/symbols/mdb/Test/Mono.Cecil.Tests/MdbTests.cs index 545ee3132..43ac3c96f 100644 --- a/symbols/mdb/Test/Mono.Cecil.Tests/MdbTests.cs +++ b/symbols/mdb/Test/Mono.Cecil.Tests/MdbTests.cs @@ -17,7 +17,7 @@ public void MdbWithJustLineInfo () AssertCode (@" .locals init (System.Int32 i) - .line 7,-1:-1,-1 'C:\sources\cecil\symbols\Mono.Cecil.Mdb\Test\Resources\assemblies\hello.cs' + .line 6,-1:-1,-1 'C:\sources\cecil\symbols\Mono.Cecil.Mdb\Test\Resources\assemblies\hello.cs' IL_0000: ldc.i4.0 IL_0001: stloc.0 .line 7,-1:-1,-1 'C:\sources\cecil\symbols\Mono.Cecil.Mdb\Test\Resources\assemblies\hello.cs' @@ -43,18 +43,5 @@ .locals init (System.Int32 i) ", main); }, symbolReaderProvider: typeof(MdbReaderProvider), symbolWriterProvider: typeof(MdbWriterProvider)); } - - static void AssertCode (string expected, MethodDefinition method) - { - Assert.IsTrue (method.HasBody); - Assert.IsNotNull (method.Body); - - Assert.AreEqual (Normalize (expected), Normalize (Formatter.FormatMethodBody (method))); - } - - static string Normalize (string str) - { - return str.Trim ().Replace ("\r\n", "\n"); - } } } diff --git a/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs b/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs index bf5793111..eef22c501 100644 --- a/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs +++ b/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs @@ -67,113 +67,6 @@ public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStre } #endif - - static class GuidMapping { - - static readonly Dictionary guid_language = new Dictionary (); - static readonly Dictionary language_guid = new Dictionary (); - - static GuidMapping () - { - AddMapping (DocumentLanguage.C, new Guid (0x63a08714, 0xfc37, 0x11d2, 0x90, 0x4c, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1)); - AddMapping (DocumentLanguage.Cpp, new Guid (0x3a12d0b7, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); - AddMapping (DocumentLanguage.CSharp, new Guid (0x3f5162f8, 0x07c6, 0x11d3, 0x90, 0x53, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1)); - AddMapping (DocumentLanguage.Basic, new Guid (0x3a12d0b8, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); - AddMapping (DocumentLanguage.Java, new Guid (0x3a12d0b4, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); - AddMapping (DocumentLanguage.Cobol, new Guid (0xaf046cd1, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc)); - AddMapping (DocumentLanguage.Pascal, new Guid (0xaf046cd2, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc)); - AddMapping (DocumentLanguage.Cil, new Guid (0xaf046cd3, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc)); - AddMapping (DocumentLanguage.JScript, new Guid (0x3a12d0b6, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); - AddMapping (DocumentLanguage.Smc, new Guid (0xd9b9f7b, 0x6611, 0x11d3, 0xbd, 0x2a, 0x0, 0x0, 0xf8, 0x8, 0x49, 0xbd)); - AddMapping (DocumentLanguage.MCpp, new Guid (0x4b35fde8, 0x07c6, 0x11d3, 0x90, 0x53, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1)); - AddMapping (DocumentLanguage.FSharp, new Guid (0xab4f38c9, 0xb6e6, 0x43ba, 0xbe, 0x3b, 0x58, 0x08, 0x0b, 0x2c, 0xcc, 0xe3)); - } - - static void AddMapping (DocumentLanguage language, Guid guid) - { - guid_language.Add (guid, language); - language_guid.Add (language, guid); - } - - static readonly Guid type_text = new Guid (0x5a869d0b, 0x6611, 0x11d3, 0xbd, 0x2a, 0x00, 0x00, 0xf8, 0x08, 0x49, 0xbd); - - 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 (0x406ea660, 0x64cf, 0x4c82, 0xb6, 0xf0, 0x42, 0xd4, 0x81, 0x72, 0xa7, 0x99); - static readonly Guid hash_sha1 = new Guid (0xff1816ec, 0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60); - - public static DocumentHashAlgorithm ToHashAlgorithm (this Guid guid) - { - if (guid == hash_md5) - return DocumentHashAlgorithm.MD5; - - if (guid == hash_sha1) - return DocumentHashAlgorithm.SHA1; - - 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; - - 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 (0x994b45c4, 0xe6e9, 0x11d2, 0x90, 0x3f, 0x00, 0xc0, 0x4f, 0xa3, 0x02, 0xa1); - - 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 (); - } - } } #if !NET_3_5 && !NET_4_0 diff --git a/symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs b/symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs index d06ac913e..8eb7c3664 100644 --- a/symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs +++ b/symbols/pdb/Mono.Cecil.Pdb/PdbReader.cs @@ -12,6 +12,8 @@ using System.Collections.Generic; using System.IO; +using Mono.Collections.Generic; + using Microsoft.Cci.Pdb; using Mono.Cecil.Cil; @@ -90,102 +92,99 @@ bool PopulateFunctions () return true; } - public void Read (MethodBody body, InstructionMapper mapper) + public MethodDebugInformation Read (MethodDefinition method) { - var method_token = body.Method.MetadataToken; + var method_token = method.MetadataToken; PdbFunction function; if (!functions.TryGetValue (method_token.ToUInt32 (), out function)) - return; + return null; - ReadSequencePoints (function, mapper); - ReadScopeAndLocals (function.scopes, null, body, mapper); - } + var symbol = new MethodDebugInformation (method); - static void ReadScopeAndLocals (PdbScope [] scopes, Scope parent, MethodBody body, InstructionMapper mapper) - { - foreach (PdbScope scope in scopes) - ReadScopeAndLocals (scope, parent, body, mapper); + ReadSequencePoints (function, symbol); + + if (function.scopes.Length > 1) + throw new NotSupportedException (); + else if (function.scopes.Length == 1) + symbol.scope = ReadScopeAndLocals (function.scopes [0], symbol); - CreateRootScope (body); + return symbol; } - static void CreateRootScope (MethodBody body) + static Collection ReadScopeAndLocals (PdbScope [] scopes, MethodDebugInformation info) { - if (!body.HasVariables) - return; - - var instructions = body.Instructions; - - var root = new Scope (); - root.Start = instructions [0]; - root.End = instructions [instructions.Count - 1]; + var symbols = new Collection (scopes.Length); - var variables = body.Variables; - for (int i = 0; i < variables.Count; i++) - root.Variables.Add (variables [i]); + foreach (PdbScope scope in scopes) + if (scope != null) + symbols.Add (ReadScopeAndLocals (scope, info)); - body.Scope = root; + return symbols; } - static void ReadScopeAndLocals (PdbScope scope, Scope parent, MethodBody body, InstructionMapper mapper) + static ScopeDebugInformation ReadScopeAndLocals (PdbScope scope, MethodDebugInformation info) { - //Scope s = new Scope (); - //s.Start = GetInstruction (body, instructions, (int) scope.address); - //s.End = GetInstruction (body, instructions, (int) scope.length - 1); - - //if (parent != null) - // parent.Scopes.Add (s); - //else - // body.Scopes.Add (s); + var parent = new ScopeDebugInformation (); + parent.Start = new InstructionOffset ((int) scope.offset); + parent.End = new InstructionOffset ((int) (scope.offset + scope.length)); - if (scope == null) - return; + if (!scope.slots.IsNullOrEmpty()) { + parent.variables = new Collection (scope.slots.Length); - foreach (PdbSlot slot in scope.slots) { - int index = (int) slot.slot; - if (index < 0 || index >= body.Variables.Count) - continue; + foreach (PdbSlot slot in scope.slots) { + var index = (int) slot.slot; + var variable = new VariableDebugInformation (index, slot.name); + if (slot.flags == 4) + variable.IsDebuggerHidden = true; + parent.variables.Add (variable); + } + } - VariableDefinition variable = body.Variables [index]; - variable.Name = slot.name; + if (!scope.constants.IsNullOrEmpty ()) { + parent.constants = new Collection (scope.constants.Length); - //s.Variables.Add (variable); + foreach (var constant in scope.constants) { + parent.constants.Add (new ConstantDebugInformation ( + constant.name, + (TypeReference) info.method.Module.LookupToken ((int) constant.token), + constant.value)); + } } - ReadScopeAndLocals (scope.scopes, null /* s */, body, mapper); + parent.scopes = ReadScopeAndLocals (scope.scopes, info); + + return parent; } - void ReadSequencePoints (PdbFunction function, InstructionMapper mapper) + void ReadSequencePoints (PdbFunction function, MethodDebugInformation info) { if (function.lines == null) return; + info.sequence_points = new Collection (); + foreach (PdbLines lines in function.lines) - ReadLines (lines, mapper); + ReadLines (lines, info); } - void ReadLines (PdbLines lines, InstructionMapper mapper) + void ReadLines (PdbLines lines, MethodDebugInformation info) { var document = GetDocument (lines.file); foreach (var line in lines.lines) - ReadLine (line, document, mapper); + ReadLine (line, document, info); } - static void ReadLine (PdbLine line, Document document, InstructionMapper mapper) + static void ReadLine (PdbLine line, Document document, MethodDebugInformation info) { - var instruction = mapper ((int) line.offset); - if (instruction == null) - return; - - var sequence_point = new SequencePoint (document); + var sequence_point = new SequencePoint ((int) line.offset, document); sequence_point.StartLine = (int) line.lineBegin; sequence_point.StartColumn = (int) line.colBegin; sequence_point.EndLine = (int) line.lineEnd; sequence_point.EndColumn = (int) line.colEnd; - instruction.SequencePoint = sequence_point; + info.sequence_points.Add (sequence_point); } Document GetDocument (PdbSource source) @@ -204,62 +203,6 @@ Document GetDocument (PdbSource source) return document; } - public void Read (MethodSymbols symbols) - { - PdbFunction function; - if (!functions.TryGetValue (symbols.MethodToken.ToUInt32 (), out function)) - return; - - ReadSequencePoints (function, symbols); - ReadLocals (function.scopes, symbols); - } - - void ReadLocals (PdbScope [] scopes, MethodSymbols symbols) - { - foreach (var scope in scopes) - ReadLocals (scope, symbols); - } - - void ReadLocals (PdbScope scope, MethodSymbols symbols) - { - if (scope == null) - return; - - foreach (var slot in scope.slots) { - int index = (int) slot.slot; - if (index < 0 || index >= symbols.Variables.Count) - continue; - - var variable = symbols.Variables [index]; - variable.Name = slot.name; - } - - ReadLocals (scope.scopes, symbols); - } - - void ReadSequencePoints (PdbFunction function, MethodSymbols symbols) - { - if (function.lines == null) - return; - - foreach (PdbLines lines in function.lines) - ReadLines (lines, symbols); - } - - void ReadLines (PdbLines lines, MethodSymbols symbols) - { - for (int i = 0; i < lines.lines.Length; i++) { - var line = lines.lines [i]; - - symbols.Instructions.Add (new InstructionSymbol ((int) line.offset, new SequencePoint (GetDocument (lines.file)) { - StartLine = (int) line.lineBegin, - StartColumn = (int) line.colBegin, - EndLine = (int) line.lineEnd, - EndColumn = (int) line.colEnd, - })); - } - } - public void Dispose () { pdb_file.Close (); diff --git a/symbols/pdb/Mono.Cecil.Pdb/PdbWriter.cs b/symbols/pdb/Mono.Cecil.Pdb/PdbWriter.cs index ab3587013..1d827b7a2 100644 --- a/symbols/pdb/Mono.Cecil.Pdb/PdbWriter.cs +++ b/symbols/pdb/Mono.Cecil.Pdb/PdbWriter.cs @@ -38,69 +38,55 @@ public bool GetDebugHeader (out ImageDebugDirectory directory, out byte [] heade return true; } - public void Write (MethodBody body) + public void Write (MethodDebugInformation info) { - var method_token = body.Method.MetadataToken; + var method_token = info.method.MetadataToken; var sym_token = new SymbolToken (method_token.ToInt32 ()); - var instructions = CollectInstructions (body); - if (instructions.Count == 0) - return; - - var start_offset = 0; - var end_offset = body.CodeSize; - writer.OpenMethod (sym_token); - writer.OpenScope (start_offset); - DefineSequencePoints (instructions); - DefineVariables (body, start_offset, end_offset); + DefineSequencePoints (info.sequence_points); + + if (info.scope != null) + DefineScope (info.scope, info); - writer.CloseScope (end_offset); writer.CloseMethod (); } - Collection CollectInstructions (MethodBody body) + void DefineScope (ScopeDebugInformation scope, MethodDebugInformation info) { - var collection = new Collection (); - var instructions = body.Instructions; - - for (int i = 0; i < instructions.Count; i++) { - var instruction = instructions [i]; - var sequence_point = instruction.SequencePoint; - if (sequence_point == null) - continue; + var start_offset = scope.Start.Offset; + var end_offset = scope.End.IsEndOfMethod + ? info.code_size + : scope.End.Offset; - GetDocument (sequence_point.Document); - collection.Add (instruction); - } - - return collection; - } + writer.OpenScope (start_offset); - void DefineVariables (MethodBody body, int start_offset, int end_offset) - { - if (!body.HasVariables) - return; + var sym_token = new SymbolToken (info.local_var_token.ToInt32 ()); - var sym_token = new SymbolToken (body.LocalVarToken.ToInt32 ()); + if (!scope.variables.IsNullOrEmpty ()) { + for (int i = 0; i < scope.variables.Count; i++) { + var variable = scope.variables [i]; + CreateLocalVariable (variable, sym_token, start_offset, end_offset); + } + } - var variables = body.Variables; - for (int i = 0; i < variables.Count; i++) { - var variable = variables [i]; - CreateLocalVariable (variable, sym_token, start_offset, end_offset); + if (!scope.scopes.IsNullOrEmpty ()) { + for (int i = 0; i < scope.scopes.Count; i++) + DefineScope (scope.scopes [i], info); } + + writer.CloseScope (end_offset); } - void DefineSequencePoints (Collection instructions) + void DefineSequencePoints (Collection sequence_points) { - for (int i = 0; i < instructions.Count; i++) { - var instruction = instructions [i]; - var sequence_point = instruction.SequencePoint; + for (int i = 0; i < sequence_points.Count; i++) { + var sequence_point = sequence_points [i]; writer.DefineSequencePoints ( GetDocument (sequence_point.Document), - new [] { instruction.Offset }, + new [] { sequence_point.Offset }, new [] { sequence_point.StartLine }, new [] { sequence_point.StartColumn }, new [] { sequence_point.EndLine }, @@ -108,11 +94,11 @@ void DefineSequencePoints (Collection instructions) } } - void CreateLocalVariable (VariableDefinition variable, SymbolToken local_var_token, int start_offset, int end_offset) + void CreateLocalVariable (VariableDebugInformation variable, SymbolToken local_var_token, int start_offset, int end_offset) { writer.DefineLocalVariable2 ( variable.Name, - 0, + variable.Attributes, local_var_token, SymAddressKind.ILOffset, variable.Index, @@ -141,55 +127,6 @@ SymDocumentWriter GetDocument (Document document) return doc_writer; } - public void Write (MethodSymbols symbols) - { - var sym_token = new SymbolToken (symbols.MethodToken.ToInt32 ()); - - var start_offset = 0; - var end_offset = symbols.CodeSize; - - writer.OpenMethod (sym_token); - writer.OpenScope (start_offset); - - DefineSequencePoints (symbols); - DefineVariables (symbols, start_offset, end_offset); - - writer.CloseScope (end_offset); - writer.CloseMethod (); - } - - void DefineSequencePoints (MethodSymbols symbols) - { - var instructions = symbols.instructions; - - for (int i = 0; i < instructions.Count; i++) { - var instruction = instructions [i]; - var sequence_point = instruction.SequencePoint; - - writer.DefineSequencePoints ( - GetDocument (sequence_point.Document), - new [] { instruction.Offset }, - new [] { sequence_point.StartLine }, - new [] { sequence_point.StartColumn }, - new [] { sequence_point.EndLine }, - new [] { sequence_point.EndColumn }); - } - } - - void DefineVariables (MethodSymbols symbols, int start_offset, int end_offset) - { - if (!symbols.HasVariables) - return; - - var sym_token = new SymbolToken (symbols.LocalVarToken.ToInt32 ()); - - var variables = symbols.Variables; - for (int i = 0; i < variables.Count; i++) { - var variable = variables [i]; - CreateLocalVariable (variable, sym_token, start_offset, end_offset); - } - } - public void Dispose () { var entry_point = module.EntryPoint; diff --git a/symbols/pdb/Mono.Cecil.Pdb/SymWriter.cs b/symbols/pdb/Mono.Cecil.Pdb/SymWriter.cs index 6a362367a..ab0893b9f 100644 --- a/symbols/pdb/Mono.Cecil.Pdb/SymWriter.cs +++ b/symbols/pdb/Mono.Cecil.Pdb/SymWriter.cs @@ -59,7 +59,7 @@ public byte[] GetDebugInfo (out ImageDebugDirectory idd) public void DefineLocalVariable2 ( string name, - FieldAttributes attributes, + VariableAttributes attributes, SymbolToken sigToken, SymAddressKind addrKind, int addr1, diff --git a/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs b/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs index f0684581d..f8b414805 100644 --- a/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs +++ b/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs @@ -60,6 +60,33 @@ .locals init (System.Int32 i, System.Int32 CS$1$0000, System.Boolean CS$4$0001) }, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider)); } + [Test] + public void DebuggerHiddenVariable () + { + TestModule ("test.exe", module => { + var type = module.GetType ("Program"); + var method = type.GetMethod ("Main"); + + var scope = method.DebugInformation.Scope; + + Assert.IsTrue (scope.HasVariables); + var variables = scope.Variables; + + Assert.AreEqual ("CS$1$0000", variables [0].Name); + Assert.IsTrue (variables [0].IsDebuggerHidden); + Assert.AreEqual ("CS$4$0001", variables [1].Name); + Assert.IsTrue (variables [1].IsDebuggerHidden); + + Assert.AreEqual (1, scope.Scopes.Count); + scope = scope.Scopes [0]; + variables = scope.Variables; + + Assert.AreEqual ("i", variables [0].Name); + Assert.IsFalse (variables [0].IsDebuggerHidden); + }, readOnly: Platform.OnMono, symbolReaderProvider: typeof(PdbReaderProvider), symbolWriterProvider: typeof(PdbWriterProvider)); + } + + [Test] public void Document () { @@ -67,7 +94,7 @@ public void Document () var type = module.GetType ("Program"); var method = type.GetMethod ("Main"); - var sequence_point = method.Body.Instructions.Where (i => i.SequencePoint != null).First ().SequencePoint; + var sequence_point = method.DebugInformation.SequencePoints.First (sp => sp != null); var document = sequence_point.Document; Assert.IsNotNull (document); @@ -87,7 +114,7 @@ public void BasicDocument () var type = module.GetType ("VBConsApp.Program"); var method = type.GetMethod ("Main"); - var sequence_point = method.Body.Instructions.Where (i => i.SequencePoint != null).First ().SequencePoint; + var sequence_point = method.DebugInformation.SequencePoints.First (sp => sp != null); var document = sequence_point.Document; Assert.IsNotNull (document); @@ -107,7 +134,7 @@ public void FSharpDocument () var type = module.GetType ("Program"); var method = type.GetMethod ("fact"); - var sequence_point = method.Body.Instructions.Where (i => i.SequencePoint != null).First ().SequencePoint; + var sequence_point = method.DebugInformation.SequencePoints.First (sp => sp != null); var document = sequence_point.Document; Assert.IsNotNull (document); @@ -137,7 +164,7 @@ public void CreateMethodFromScratch () body.InitLocals = true; var il = body.GetILProcessor (); - var temp = new VariableDefinition ("temp", module.ImportReference (typeof (string))); + var temp = new VariableDefinition (module.ImportReference (typeof (string))); body.Variables.Add (temp); il.Emit (OpCodes.Nop); @@ -146,13 +173,19 @@ public void CreateMethodFromScratch () il.Emit (OpCodes.Ldloc, temp); il.Emit (OpCodes.Ret); - body.Instructions [0].SequencePoint = new SequencePoint (new Document (@"C:\test.cs")) { + var sequence_point = new SequencePoint (body.Instructions [0], new Document (@"C:\test.cs")) { StartLine = 0, StartColumn = 0, EndLine = 0, EndColumn = 4, }; + method.DebugInformation.SequencePoints.Add (sequence_point); + + method.DebugInformation.Scope = new ScopeDebugInformation (body.Instructions [0], null) { + Variables = { new VariableDebugInformation (temp, "temp") } + }; + var file = Path.Combine (Path.GetTempPath (), "Pan.dll"); module.Write (file, new WriterParameters { SymbolWriterProvider = new PdbWriterProvider (), @@ -164,20 +197,7 @@ public void CreateMethodFromScratch () method = module.GetType ("Pin.Pon").GetMethod ("Pang"); - Assert.AreEqual ("temp", method.Body.Variables [0].Name); - } - - static void AssertCode (string expected, MethodDefinition method) - { - Assert.IsTrue (method.HasBody); - Assert.IsNotNull (method.Body); - - Assert.AreEqual (Normalize (expected), Normalize (Formatter.FormatMethodBody (method))); - } - - static string Normalize (string str) - { - return str.Trim ().Replace ("\r\n", "\n"); + Assert.AreEqual ("temp", method.DebugInformation.Scope.Variables [0].Name); } } } diff --git a/symbols/pdb/Test/Resources/assemblies/PdbTarget.exe b/symbols/pdb/Test/Resources/assemblies/PdbTarget.exe new file mode 100644 index 0000000000000000000000000000000000000000..e08f88a2956121828dfd64f951cfc4b1e1449e2e GIT binary patch literal 10240 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 literal 0 HcmV?d00001 diff --git a/symbols/pdb/Test/Resources/assemblies/PdbTarget.pdb b/symbols/pdb/Test/Resources/assemblies/PdbTarget.pdb new file mode 100644 index 0000000000000000000000000000000000000000..f9ef6a0be0110ead2ee71d460b16c4bc1bc6e3f8 GIT binary patch literal 1692 zcmZWqZ%kWN6hHU8_VphHS}1?2Otv9T+$z&eC&oAm8?cN}D03tbwRByFE4=Vthtn8n zf<`}@xKBporp7S8Es?kw6%(0@8kZP#F-F}dKNyUf_(6;__&c|+rir&X_nm+Dp5Hn5 z-qU3INK%m^88x6(f3kgHZ=zc($fRe$6hS*vC#FUBJ7^a}ULc{t4@dxcp7A)DU@9e8zto^z^c=6Jhv3KRhMsoGJO7sJm#R@hp9&~J?Zir;9GSlrmjjz_}=#)kL~_9m@a6$0@})X z?12{pMMds(Wrjv_mK+V(WrYmE@2Qd-A$zqfnGhWWi7Y;qI*Kg62yAz_b`u#3Uk@^2 z^XUo@JqX!XC4UUr4>{!81y8U_4nq!C$)7`xRmtbdur+!^BP!RMH5xd zuOcs|>7$W1_`-Vj%JLuYd^2#l+3jaQf8yk96OdztZ*3`0YQ( z55Cg%*GO}{4OkPyM-5Xk8;7{B$LCmQ>}<{n;K_|6e6Hw8CbEuqs-~`ad*joCA1tfM zPaCWQ`+q!Fd-b!xy`66cQ?`}2GqV-1-o|S+hl_20UvKz!Wj^y|=w18!lkvs7q|i-1 zgE&Od(ls1f6p5mO!L|JmaBUUUF^r0r%=A-EF*h48e-eFGp^(cKXRJ9VF_4?f*)!RI zYZ@A9a=GzSb}n-QjUX|eaZWppu6km&kQmE3R$(D$JH}zlihGqRy`)MntJ10}tudFb z8;6Y1Kxt$6ZXi@KLy?bJ;oNrN`7*Gb_5j&D-l2zhsokWg`Iui|#&8~LH~hmjz#SG> zXj^NuIIuY!S&`cHY|{+nJo)?xK&4CSR<7NelI-ut;-CkIF0V)`5M*XD8DX&#bROtJ ze&`w*mp$Y`2%xAG%aouR3LYsh0f;z&^ZKQm)<;UKB(174?nFXr3NcY=KPIe2H{C(^ zFzu1!@XH1hdMl+^9-zvX%MlQzys!r%hDmKqqtc=}NVS#iKu%rglCsB41kRSiHRoo@ z1(4nBqN1q+942-;ZXp$&1Tg94dh}w>fW|=mpg!p~*d$776w!7tqg^aegr!BeH)lI@ tl;|vC;(r8CkqHx;c)Tp==0p!+pGi>c2TV7G(J?EH01CPcdQBLje*u>z(ANL} literal 0 HcmV?d00001