diff options
30 files changed, 397 insertions, 372 deletions
diff --git a/Mono.Cecil.Cil/CodeReader.cs b/Mono.Cecil.Cil/CodeReader.cs index c4b0993..f102d68 100644 --- a/Mono.Cecil.Cil/CodeReader.cs +++ b/Mono.Cecil.Cil/CodeReader.cs @@ -17,58 +17,40 @@ using RVA = System.UInt32; namespace Mono.Cecil.Cil { - sealed class CodeReader : ByteBuffer { + sealed class CodeReader : BinaryStreamReader { readonly internal MetadataReader reader; int start; - Section code_section; MethodDefinition method; MethodBody body; int Offset { - get { return base.position - start; } + get { return Position - start; } } - public CodeReader (Section section, MetadataReader reader) - : base (section.Data) + public CodeReader (MethodDefinition method, MetadataReader reader) + : base (reader.image.Stream) { - this.code_section = section; this.reader = reader; + this.reader.context = method; + this.Position = (int) reader.image.ResolveVirtualAddress ((uint) method.RVA); } - public MethodBody ReadMethodBody (MethodDefinition method) + public static MethodBody ReadMethodBody (MethodDefinition method, MetadataReader metadata) { - this.method = method; - this.body = new MethodBody (method); + var reader = new CodeReader (method, metadata); + reader.method = method; + reader.body = new MethodBody (method); - reader.context = method; + reader.ReadMethodBody (); - ReadMethodBody (); - - return this.body; - } - - public void MoveTo (int rva) - { - if (!IsInSection (rva)) { - code_section = reader.image.GetSectionAtVirtualAddress ((uint) rva); - Reset (code_section.Data); - } - - base.position = rva - (int) code_section.VirtualAddress; - } - - bool IsInSection (int rva) - { - return code_section.VirtualAddress <= rva && rva < code_section.VirtualAddress + code_section.SizeOfRawData; + return reader.body; } void ReadMethodBody () { - MoveTo (method.RVA); - var flags = ReadByte (); switch (flags & 0x3) { case 0x2: // tiny @@ -77,7 +59,7 @@ namespace Mono.Cecil.Cil { ReadCode (); break; case 0x3: // fat - base.position--; + Advance (-1); ReadFatMethod (); break; default: @@ -209,17 +191,17 @@ namespace Mono.Cecil.Cil { void ReadCode () { - start = position; + start = Position; var code_size = body.code_size; - if (code_size < 0 || buffer.Length <= (uint) (code_size + position)) + if (code_size < 0 || Length <= (uint) (code_size + Position)) code_size = 0; var end = start + code_size; var instructions = body.instructions = new InstructionCollection ((code_size + 1) / 2); - while (position < end) { - var offset = base.position - start; + while (Position < end) { + var offset = Position - start; var opcode = ReadOpCode (); var current = new Instruction (offset, opcode); @@ -394,7 +376,7 @@ namespace Mono.Cecil.Cil { void ReadFatSection () { - position--; + Advance (-1); var count = (ReadInt32 () >> 8) / 24; ReadExceptionHandlers ( @@ -440,6 +422,7 @@ namespace Mono.Cecil.Cil { void Align (int align) { align--; + var position = Position; Advance (((position + align) & ~align) - position); } @@ -454,11 +437,6 @@ namespace Mono.Cecil.Cil { { var buffer = new ByteBuffer (); - this.method = method; - reader.context = method; - - MoveTo (method.RVA); - var flags = ReadByte (); switch (flags & 0x3) { @@ -469,8 +447,7 @@ namespace Mono.Cecil.Cil { PatchRawCode (buffer, code_size, writer); break; case 0x3: // fat - base.position--; - + Advance (-1); PatchRawFatMethod (buffer, writer, out code_size, out local_var_token); break; default: @@ -571,9 +548,9 @@ namespace Mono.Cecil.Cil { void PatchRawSection (ByteBuffer buffer, MetadataBuilder metadata) { - var position = base.position; + var position = Position; Align (4); - buffer.WriteBytes (base.position - position); + buffer.WriteBytes (Position - position); const byte fat_format = 0x40; const byte more_sects = 0x80; @@ -604,7 +581,7 @@ namespace Mono.Cecil.Cil { void PatchRawFatSection (ByteBuffer buffer, MetadataBuilder metadata) { - position--; + Advance (-1); var length = ReadInt32 (); buffer.WriteInt32 (length); diff --git a/Mono.Cecil.Cil/CodeWriter.cs b/Mono.Cecil.Cil/CodeWriter.cs index 58c9277..6659a10 100644 --- a/Mono.Cecil.Cil/CodeWriter.cs +++ b/Mono.Cecil.Cil/CodeWriter.cs @@ -75,7 +75,7 @@ namespace Mono.Cecil.Cil { void WriteUnresolvedMethodBody (MethodDefinition method) { - var code_reader = metadata.module.Read (method, (_, reader) => reader.code); + var code_reader = metadata.module.Read (method, (m, reader) => new CodeReader (m, reader)); int code_size; MetadataToken local_var_token; diff --git a/Mono.Cecil.Cil/PortablePdb.cs b/Mono.Cecil.Cil/PortablePdb.cs index 4ed2eca..22f1ac6 100644 --- a/Mono.Cecil.Cil/PortablePdb.cs +++ b/Mono.Cecil.Cil/PortablePdb.cs @@ -26,7 +26,7 @@ namespace Mono.Cecil.Cil { Mixin.CheckModule (module); using (var file = File.OpenRead (GetPdbFileName (fileName))) - return GetSymbolReader (module, file); + return GetSymbolReader (module, file, file.Name); } static string GetPdbFileName (string assemblyFileName) @@ -39,7 +39,12 @@ namespace Mono.Cecil.Cil { Mixin.CheckModule (module); Mixin.CheckStream (symbolStream); - return new PortablePdbReader (ImageReader.ReadPortablePdb (symbolStream), module); + return GetSymbolReader (module, symbolStream, ""); + } + + ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream, string fileName) + { + return new PortablePdbReader (ImageReader.ReadPortablePdb (symbolStream, fileName), module); } } @@ -124,6 +129,7 @@ namespace Mono.Cecil.Cil { public void Dispose () { + image.Dispose (); } } diff --git a/Mono.Cecil.Metadata/BlobHeap.cs b/Mono.Cecil.Metadata/BlobHeap.cs index f63d553..574a130 100644 --- a/Mono.Cecil.Metadata/BlobHeap.cs +++ b/Mono.Cecil.Metadata/BlobHeap.cs @@ -10,25 +10,21 @@ using System; -using Mono.Cecil.PE; - namespace Mono.Cecil.Metadata { sealed class BlobHeap : Heap { - public BlobHeap (Section section, uint start, uint size) - : base (section, start, size) + public BlobHeap (byte [] data) + : base (data) { } public byte [] Read (uint index) { - if (index == 0 || index > Size - 1) + if (index == 0 || index > this.data.Length - 1) return Empty<byte>.Array; - var data = Section.Data; - - int position = (int) (index + Offset); + int position = (int) index; int length = (int) data.ReadCompressedUInt32 (ref position); if (length > data.Length - position) @@ -43,15 +39,15 @@ namespace Mono.Cecil.Metadata { public void GetView (uint signature, out byte [] buffer, out int index, out int length) { - if (signature == 0 || signature > Size - 1) { + if (signature == 0 || signature > data.Length - 1) { buffer = null; index = length = 0; return; } - buffer = Section.Data; + buffer = data; - index = (int) (signature + Offset); + index = (int) signature; length = (int) buffer.ReadCompressedUInt32 (ref index); } } diff --git a/Mono.Cecil.Metadata/GuidHeap.cs b/Mono.Cecil.Metadata/GuidHeap.cs index 9fbe5da..76ec9d1 100644 --- a/Mono.Cecil.Metadata/GuidHeap.cs +++ b/Mono.Cecil.Metadata/GuidHeap.cs @@ -10,14 +10,12 @@ using System; -using Mono.Cecil.PE; - namespace Mono.Cecil.Metadata { sealed class GuidHeap : Heap { - public GuidHeap (Section section, uint start, uint size) - : base (section, start, size) + public GuidHeap (byte [] data) + : base (data) { } @@ -25,12 +23,12 @@ namespace Mono.Cecil.Metadata { { const int guid_size = 16; - if (index == 0 || ((index - 1) + guid_size) > Size) + if (index == 0 || ((index - 1) + guid_size) > data.Length) return new Guid (); var buffer = new byte [guid_size]; - Buffer.BlockCopy (Section.Data, (int) (Offset + ((index - 1) * guid_size)), buffer, 0, guid_size); + Buffer.BlockCopy (this.data, (int) ((index - 1) * guid_size), buffer, 0, guid_size); return new Guid (buffer); } diff --git a/Mono.Cecil.Metadata/Heap.cs b/Mono.Cecil.Metadata/Heap.cs index c600f46..1badfbb 100644 --- a/Mono.Cecil.Metadata/Heap.cs +++ b/Mono.Cecil.Metadata/Heap.cs @@ -8,23 +8,17 @@ // Licensed under the MIT/X11 license. // -using Mono.Cecil.PE; - namespace Mono.Cecil.Metadata { abstract class Heap { public int IndexSize; - public readonly Section Section; - public readonly uint Offset; - public readonly uint Size; + internal byte [] data; - protected Heap (Section section, uint offset, uint size) + protected Heap (byte [] data) { - this.Section = section; - this.Offset = offset; - this.Size = size; + this.data = data; } } } diff --git a/Mono.Cecil.Metadata/PdbHeap.cs b/Mono.Cecil.Metadata/PdbHeap.cs index 4532e8f..39e275a 100644 --- a/Mono.Cecil.Metadata/PdbHeap.cs +++ b/Mono.Cecil.Metadata/PdbHeap.cs @@ -21,8 +21,8 @@ namespace Mono.Cecil.Metadata { public long TypeSystemTables; public uint [] TypeSystemTableRows; - public PdbHeap (Section section, uint offset, uint size) - : base (section, offset, size) + public PdbHeap (byte [] data) + : base (data) { } diff --git a/Mono.Cecil.Metadata/StringHeap.cs b/Mono.Cecil.Metadata/StringHeap.cs index ee6009a..4bde70e 100644 --- a/Mono.Cecil.Metadata/StringHeap.cs +++ b/Mono.Cecil.Metadata/StringHeap.cs @@ -12,16 +12,14 @@ using System; using System.Collections.Generic; using System.Text; -using Mono.Cecil.PE; - namespace Mono.Cecil.Metadata { class StringHeap : Heap { readonly Dictionary<uint, string> strings = new Dictionary<uint, string> (); - public StringHeap (Section section, uint start, uint size) - : base (section, start, size) + public StringHeap (byte [] data) + : base (data) { } @@ -34,7 +32,7 @@ namespace Mono.Cecil.Metadata { if (strings.TryGetValue (index, out @string)) return @string; - if (index > Size - 1) + if (index > data.Length - 1) return string.Empty; @string = ReadStringAt (index); @@ -47,8 +45,7 @@ namespace Mono.Cecil.Metadata { protected virtual string ReadStringAt (uint index) { int length = 0; - byte [] data = Section.Data; - int start = (int) (index + Offset); + int start = (int) index; for (int i = start; ; i++) { if (data [i] == 0) diff --git a/Mono.Cecil.Metadata/TableHeap.cs b/Mono.Cecil.Metadata/TableHeap.cs index 33997ab..ebc802b 100644 --- a/Mono.Cecil.Metadata/TableHeap.cs +++ b/Mono.Cecil.Metadata/TableHeap.cs @@ -87,8 +87,8 @@ namespace Mono.Cecil.Metadata { get { return Tables [(int) table]; } } - public TableHeap (Section section, uint start, uint size) - : base (section, start, size) + public TableHeap (byte [] data) + : base (data) { } diff --git a/Mono.Cecil.Metadata/UserStringHeap.cs b/Mono.Cecil.Metadata/UserStringHeap.cs index eb4b0d3..7b1b42f 100644 --- a/Mono.Cecil.Metadata/UserStringHeap.cs +++ b/Mono.Cecil.Metadata/UserStringHeap.cs @@ -8,23 +8,18 @@ // Licensed under the MIT/X11 license. // -using System; - -using Mono.Cecil.PE; - namespace Mono.Cecil.Metadata { sealed class UserStringHeap : StringHeap { - public UserStringHeap (Section section, uint start, uint size) - : base (section, start, size) + public UserStringHeap (byte [] data) + : base (data) { } protected override string ReadStringAt (uint index) { - byte [] data = Section.Data; - int start = (int) (index + Offset); + int start = (int) index; uint length = (uint) (data.ReadCompressedUInt32 (ref start) & ~1); if (length < 1) diff --git a/Mono.Cecil.PE/BinaryStreamReader.cs b/Mono.Cecil.PE/BinaryStreamReader.cs index dbb2c30..eb4b77e 100644 --- a/Mono.Cecil.PE/BinaryStreamReader.cs +++ b/Mono.Cecil.PE/BinaryStreamReader.cs @@ -15,17 +15,31 @@ namespace Mono.Cecil.PE { class BinaryStreamReader : BinaryReader { + public int Position { + get { return (int) BaseStream.Position; } + set { BaseStream.Position = value; } + } + + public int Length { + get { return (int) BaseStream.Length; } + } + public BinaryStreamReader (Stream stream) : base (stream) { } - protected void Advance (int bytes) + public void Advance (int bytes) { BaseStream.Seek (bytes, SeekOrigin.Current); } - protected DataDirectory ReadDataDirectory () + public void MoveTo (uint position) + { + BaseStream.Seek (position, SeekOrigin.Begin); + } + + public DataDirectory ReadDataDirectory () { return new DataDirectory (ReadUInt32 (), ReadUInt32 ()); } diff --git a/Mono.Cecil.PE/ByteBuffer.cs b/Mono.Cecil.PE/ByteBuffer.cs index 9665c2a..8aee04b 100644 --- a/Mono.Cecil.PE/ByteBuffer.cs +++ b/Mono.Cecil.PE/ByteBuffer.cs @@ -34,12 +34,6 @@ namespace Mono.Cecil.PE { this.length = this.buffer.Length; } - public void Reset (byte [] buffer) - { - this.buffer = buffer ?? Empty<byte>.Array; - this.length = this.buffer.Length; - } - public void Advance (int length) { position += length; diff --git a/Mono.Cecil.PE/Image.cs b/Mono.Cecil.PE/Image.cs index 3472fe3..d0fd80d 100644 --- a/Mono.Cecil.PE/Image.cs +++ b/Mono.Cecil.PE/Image.cs @@ -9,8 +9,8 @@ // using System; +using System.IO; -using Mono; using Mono.Cecil.Cil; using Mono.Cecil.Metadata; @@ -18,13 +18,15 @@ using RVA = System.UInt32; namespace Mono.Cecil.PE { - sealed class Image { + sealed class Image : IDisposable { + + public Stream Stream; + public string FileName; public ModuleKind Kind; public string RuntimeVersion; public TargetArchitecture Architecture; public ModuleCharacteristics Characteristics; - public string FileName; public Section [] Sections; @@ -116,32 +118,40 @@ namespace Mono.Cecil.PE { return null; } - public ImageDebugDirectory GetDebugHeader (out byte [] header) + public BinaryStreamReader GetReaderAt (RVA rva) { - var section = GetSectionAtVirtualAddress (Debug.VirtualAddress); - var buffer = new ByteBuffer (section.Data); - buffer.position = (int) (Debug.VirtualAddress - section.VirtualAddress); + var section = GetSectionAtVirtualAddress (rva); + if (section == null) + return null; - var directory = new ImageDebugDirectory { - Characteristics = buffer.ReadInt32 (), - TimeDateStamp = buffer.ReadInt32 (), - MajorVersion = buffer.ReadInt16 (), - MinorVersion = buffer.ReadInt16 (), - Type = buffer.ReadInt32 (), - SizeOfData = buffer.ReadInt32 (), - AddressOfRawData = buffer.ReadInt32 (), - PointerToRawData = buffer.ReadInt32 (), - }; + var reader = new BinaryStreamReader (Stream); + reader.MoveTo (ResolveVirtualAddressInSection (rva, section)); + return reader; + } - if (directory.SizeOfData == 0 || directory.PointerToRawData == 0) { + public ImageDebugDirectory GetDebugHeader (out byte [] header) + { + var reader = GetReaderAt (Debug.VirtualAddress); + if (reader == null) { header = Empty<byte>.Array; - return directory; + return new ImageDebugDirectory (); } - buffer.position = (int) (directory.PointerToRawData - section.PointerToRawData); + var directory = new ImageDebugDirectory { + Characteristics = reader.ReadInt32 (), + TimeDateStamp = reader.ReadInt32 (), + MajorVersion = reader.ReadInt16 (), + MinorVersion = reader.ReadInt16 (), + Type = reader.ReadInt32 (), + SizeOfData = reader.ReadInt32 (), + AddressOfRawData = reader.ReadInt32 (), + PointerToRawData = reader.ReadInt32 (), + }; - header = new byte [directory.SizeOfData]; - Buffer.BlockCopy (buffer.buffer, buffer.position, header, 0, header.Length); + reader = GetReaderAt ((uint) directory.AddressOfRawData); + header = reader != null + ? reader.ReadBytes (directory.SizeOfData) + : Empty<byte>.Array; return directory; } @@ -156,5 +166,10 @@ namespace Mono.Cecil.PE { || HasTable (Table.StateMachineMethod) || HasTable (Table.CustomDebugInformation); } + + public void Dispose () + { + Stream.Dispose (); + } } } diff --git a/Mono.Cecil.PE/ImageReader.cs b/Mono.Cecil.PE/ImageReader.cs index 00f0759..06a864d 100644 --- a/Mono.Cecil.PE/ImageReader.cs +++ b/Mono.Cecil.PE/ImageReader.cs @@ -24,12 +24,14 @@ namespace Mono.Cecil.PE { DataDirectory cli; DataDirectory metadata; - public ImageReader (Stream stream) + uint table_heap_offset; + + public ImageReader (Stream stream, string file_name) : base (stream) { image = new Image (); - - image.FileName = stream.GetFullyQualifiedName (); + image.Stream = stream; + image.FileName = file_name; } void MoveTo (DataDirectory directory) @@ -37,11 +39,6 @@ namespace Mono.Cecil.PE { BaseStream.Position = image.ResolveVirtualAddress (directory.VirtualAddress); } - void MoveTo (uint position) - { - BaseStream.Position = position; - } - void ReadImage () { if (BaseStream.Length < 128) @@ -261,31 +258,11 @@ namespace Mono.Cecil.PE { Advance (16); sections [i] = section; - - ReadSectionData (section); } image.Sections = sections; } - void ReadSectionData (Section section) - { - var position = BaseStream.Position; - - MoveTo (section.PointerToRawData); - - var length = (int) section.SizeOfRawData; - var data = new byte [length]; - int offset = 0, read; - - while ((read = Read (data, offset, length - offset)) > 0) - offset += read; - - section.Data = data; - - BaseStream.Position = position; - } - void ReadCLIHeader () { MoveTo (cli); @@ -351,42 +328,53 @@ namespace Mono.Cecil.PE { void ReadMetadataStream (Section section) { // Offset 4 - uint start = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32 (); // relative to the section start + uint offset = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32 (); // relative to the section start // Size 4 uint size = ReadUInt32 (); + var data = ReadHeapData (offset, size); + var name = ReadAlignedString (16); switch (name) { case "#~": case "#-": - image.TableHeap = new TableHeap (section, start, size); + image.TableHeap = new TableHeap (data); + table_heap_offset = offset; break; case "#Strings": - image.StringHeap = new StringHeap (section, start, size); + image.StringHeap = new StringHeap (data); break; case "#Blob": - image.BlobHeap = new BlobHeap (section, start, size); + image.BlobHeap = new BlobHeap (data); break; case "#GUID": - image.GuidHeap = new GuidHeap (section, start, size); + image.GuidHeap = new GuidHeap (data); break; case "#US": - image.UserStringHeap = new UserStringHeap (section, start, size); + image.UserStringHeap = new UserStringHeap (data); break; case "#Pdb": - image.PdbHeap = new PdbHeap (section, start, size); + image.PdbHeap = new PdbHeap (data); break; } } + byte [] ReadHeapData (uint offset, uint size) + { + var position = BaseStream.Position; + MoveTo (offset + image.MetadataSection.PointerToRawData); + var data = ReadBytes ((int) size); + BaseStream.Position = position; + + return data; + } + void ReadTableHeap () { var heap = image.TableHeap; - uint start = heap.Section.PointerToRawData; - - MoveTo (heap.Offset + start); + MoveTo (table_heap_offset + image.MetadataSection.PointerToRawData); // Reserved 4 // MajorVersion 1 @@ -439,7 +427,7 @@ namespace Mono.Cecil.PE { void ComputeTableInformations () { - uint offset = (uint) BaseStream.Position - image.MetadataSection.PointerToRawData; // header + uint offset = (uint) BaseStream.Position - table_heap_offset - image.MetadataSection.PointerToRawData; // header int stridx_size = image.StringHeap.IndexSize; int guididx_size = image.GuidHeap.IndexSize; @@ -700,13 +688,11 @@ namespace Mono.Cecil.PE { { var heap = image.PdbHeap; - uint start = heap.Section.PointerToRawData; - - MoveTo (heap.Offset + start); + var buffer = new ByteBuffer (heap.data); - heap.Id = ReadBytes (20); - heap.EntryPoint = ReadUInt32 (); - heap.TypeSystemTables = ReadInt64 (); + heap.Id = buffer.ReadBytes (20); + heap.EntryPoint = buffer.ReadUInt32 (); + heap.TypeSystemTables = buffer.ReadInt64 (); heap.TypeSystemTableRows = new uint [Mixin.TableCount]; for (int i = 0; i < Mixin.TableCount; i++) { @@ -714,14 +700,14 @@ namespace Mono.Cecil.PE { if (!heap.HasTable (table)) continue; - heap.TypeSystemTableRows [i] = ReadUInt32 (); + heap.TypeSystemTableRows [i] = buffer.ReadUInt32 (); } } - public static Image ReadImage (Stream stream) + public static Image ReadImage (Stream stream, string file_name) { try { - var reader = new ImageReader (stream); + var reader = new ImageReader (stream, file_name); reader.ReadImage (); return reader.image; } catch (EndOfStreamException e) { @@ -729,10 +715,10 @@ namespace Mono.Cecil.PE { } } - public static Image ReadPortablePdb (Stream stream) + public static Image ReadPortablePdb (Stream stream, string file_name) { try { - var reader = new ImageReader (stream); + var reader = new ImageReader (stream, file_name); var length = (uint) stream.Length; reader.image.Sections = new[] { @@ -741,7 +727,6 @@ namespace Mono.Cecil.PE { SizeOfRawData = length, VirtualAddress = 0, VirtualSize = length, - Data = stream.ReadAll (), } }; diff --git a/Mono.Cecil.PE/ImageWriter.cs b/Mono.Cecil.PE/ImageWriter.cs index ae59040..8f88120 100644 --- a/Mono.Cecil.PE/ImageWriter.cs +++ b/Mono.Cecil.PE/ImageWriter.cs @@ -86,9 +86,8 @@ namespace Mono.Cecil.PE { if (rsrc == null) return; - var raw_resources = new byte [rsrc.Data.Length]; - Buffer.BlockCopy (rsrc.Data, 0, raw_resources, 0, rsrc.Data.Length); - win32_resources = new ByteBuffer (raw_resources); + var reader = module.Image.GetReaderAt (rsrc.VirtualAddress); + win32_resources = new ByteBuffer (reader.ReadBytes ((int) rsrc.SizeOfRawData)); } Section GetImageResourceSection () diff --git a/Mono.Cecil.PE/Section.cs b/Mono.Cecil.PE/Section.cs index d32365a..49d8e90 100644 --- a/Mono.Cecil.PE/Section.cs +++ b/Mono.Cecil.PE/Section.cs @@ -20,6 +20,5 @@ namespace Mono.Cecil.PE { public uint VirtualSize; public uint SizeOfRawData; public uint PointerToRawData; - public byte [] Data; } } diff --git a/Mono.Cecil/AssemblyDefinition.cs b/Mono.Cecil/AssemblyDefinition.cs index 0cc935e..06219b7 100644 --- a/Mono.Cecil/AssemblyDefinition.cs +++ b/Mono.Cecil/AssemblyDefinition.cs @@ -15,7 +15,7 @@ using Mono.Collections.Generic; namespace Mono.Cecil { - public sealed class AssemblyDefinition : ICustomAttributeProvider, ISecurityDeclarationProvider { + public sealed class AssemblyDefinition : ICustomAttributeProvider, ISecurityDeclarationProvider, IDisposable { AssemblyNameDefinition name; @@ -89,6 +89,18 @@ namespace Mono.Cecil { { } + public void Dispose () + { + if (this.modules == null) { + main_module.Dispose (); + return; + } + + var modules = this.Modules; + for (int i = 0; i < modules.Count; i++) + modules [i].Dispose (); + } + #if !READ_ONLY public static AssemblyDefinition CreateAssembly (AssemblyNameDefinition assemblyName, string moduleName, ModuleKind kind) { diff --git a/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil/AssemblyReader.cs index 3e16a31..540d573 100644 --- a/Mono.Cecil/AssemblyReader.cs +++ b/Mono.Cecil/AssemblyReader.cs @@ -102,7 +102,7 @@ namespace Mono.Cecil { var reader = parameters.SymbolStream != null ? symbol_reader_provider.GetSymbolReader (module, parameters.SymbolStream) - : symbol_reader_provider.GetSymbolReader (module, module.FullyQualifiedName); + : symbol_reader_provider.GetSymbolReader (module, module.FileName); module.ReadSymbols (reader); } @@ -414,7 +414,6 @@ namespace Mono.Cecil { readonly internal MetadataSystem metadata; internal IGenericContext context; - internal CodeReader code; readonly MetadataReader metadata_reader; @@ -424,21 +423,19 @@ namespace Mono.Cecil { } public MetadataReader (ModuleDefinition module) - : base (module.Image.MetadataSection.Data) + : base (module.Image.TableHeap.data) { this.image = module.Image; this.module = module; this.metadata = module.MetadataSystem; - this.code = new CodeReader (image.MetadataSection, this); } public MetadataReader (Image image, ModuleDefinition module, MetadataReader metadata_reader) - : base (image.MetadataSection.Data) + : base (image.TableHeap.data) { this.image = image; this.module = module; this.metadata = module.MetadataSystem; - this.code = new CodeReader (image.MetadataSection, this); this.metadata_reader = metadata_reader; } @@ -648,10 +645,10 @@ namespace Mono.Cecil { #if !PCL string GetModuleFileName (string name) { - if (module.FullyQualifiedName == null) + if (module.FileName == null) throw new NotSupportedException (); - var path = Path.GetDirectoryName (module.FullyQualifiedName); + var path = Path.GetDirectoryName (module.FileName); return Path.Combine (path, name); } #endif @@ -746,17 +743,12 @@ namespace Mono.Cecil { public MemoryStream GetManagedResourceStream (uint offset) { - var rva = image.Resources.VirtualAddress; - var section = image.GetSectionAtVirtualAddress (rva); - var position = (rva - section.VirtualAddress) + offset; - var buffer = section.Data; + var reader = image.GetReaderAt (image.Resources.VirtualAddress); + if (reader == null) + return new MemoryStream (); - var length = buffer [position] - | (buffer [position + 1] << 8) - | (buffer [position + 2] << 16) - | (buffer [position + 3] << 24); - - return new MemoryStream (buffer, (int) position + 4, length); + reader.Advance ((int) offset); + return new MemoryStream (reader.ReadBytes (reader.ReadInt32 ())); } void PopulateVersionAndFlags (AssemblyNameReference name) @@ -1317,13 +1309,10 @@ namespace Mono.Cecil { byte [] GetFieldInitializeValue (int size, RVA rva) { - var section = image.GetSectionAtVirtualAddress (rva); - if (section == null) - return Empty<byte>.Array; - - var value = new byte [size]; - Buffer.BlockCopy (section.Data, (int) (rva - section.VirtualAddress), value, 0, size); - return value; + var reader = image.GetReaderAt (rva); + return reader != null + ? reader.ReadBytes (size) + : Empty<byte>.Array; } static int GetFieldTypeSize (TypeReference type) @@ -2102,7 +2091,7 @@ namespace Mono.Cecil { public MethodBody ReadMethodBody (MethodDefinition method) { - return code.ReadMethodBody (method); + return CodeReader.ReadMethodBody (method, this); } public CallSite ReadCallSite (MetadataToken token) @@ -3159,19 +3148,12 @@ namespace Mono.Cecil { } public SignatureReader (uint blob, MetadataReader reader) - : base (reader.buffer) + : base (reader.image.BlobHeap.data) { this.reader = reader; - - MoveToBlob (blob); - - this.sig_length = ReadCompressedUInt32 (); - this.start = (uint) position; - } - - void MoveToBlob (uint blob) - { - position = (int) (reader.image.BlobHeap.Offset + blob); + this.position = (int) blob; + this.sig_length = ReadCompressedUInt32(); + this.start = (uint) this.position; } MetadataToken ReadTypeTokenSignature () diff --git a/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil/AssemblyWriter.cs index e35e2d5..1fd4a61 100644 --- a/Mono.Cecil/AssemblyWriter.cs +++ b/Mono.Cecil/AssemblyWriter.cs @@ -108,6 +108,10 @@ namespace Mono.Cecil { module.symbol_reader.Dispose (); var writer = ImageWriter.CreateWriter (module, metadata, stream); + + if (module.HasImage) + module.Image.Dispose (); + writer.WriteImage (); if (metadata.symbol_writer != null) diff --git a/Mono.Cecil/DefaultAssemblyResolver.cs b/Mono.Cecil/DefaultAssemblyResolver.cs index aa4e278..7e47637 100644 --- a/Mono.Cecil/DefaultAssemblyResolver.cs +++ b/Mono.Cecil/DefaultAssemblyResolver.cs @@ -15,7 +15,9 @@ using System.Collections.Generic; namespace Mono.Cecil { - public class DefaultAssemblyResolver : BaseAssemblyResolver { + class AssemblyResolver : BaseAssemblyResolver {} + + public class DefaultAssemblyResolver : BaseAssemblyResolver, IDisposable { readonly IDictionary<string, AssemblyDefinition> cache; @@ -50,6 +52,14 @@ namespace Mono.Cecil { cache [name] = assembly; } + + public void Dispose () + { + foreach (var assembly in cache.Values) + assembly.Dispose (); + + cache.Clear (); + } } } diff --git a/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil/ModuleDefinition.cs index bd23bce..cf3dd29 100644 --- a/Mono.Cecil/ModuleDefinition.cs +++ b/Mono.Cecil/ModuleDefinition.cs @@ -40,12 +40,18 @@ namespace Mono.Cecil { Stream symbol_stream; ISymbolReaderProvider symbol_reader_provider; bool read_symbols; + bool in_memory; public ReadingMode ReadingMode { get { return reading_mode; } set { reading_mode = value; } } + public bool InMemory { + get { return in_memory; } + set { in_memory = value; } + } + public IAssemblyResolver AssemblyResolver { get { return assembly_resolver; } set { assembly_resolver = value; } @@ -93,6 +99,7 @@ namespace Mono.Cecil { public ReaderParameters (ReadingMode readingMode) { this.reading_mode = readingMode; + this.in_memory = true; // back compatibility } } @@ -213,7 +220,7 @@ namespace Mono.Cecil { #endif - public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider { + public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider, IDisposable { internal Image Image; internal MetadataSystem MetadataSystem; @@ -224,9 +231,8 @@ namespace Mono.Cecil { internal IAssemblyResolver assembly_resolver; internal IMetadataResolver metadata_resolver; internal TypeSystem type_system; - internal readonly MetadataReader reader; - readonly string fq_name; + readonly string file_name; internal string runtime_version; internal ModuleKind kind; @@ -292,8 +298,13 @@ namespace Mono.Cecil { set { characteristics = value; } } + [Obsolete("Use FileName")] public string FullyQualifiedName { - get { return fq_name; } + get { return file_name; } + } + + public string FileName { + get { return file_name; } } public Guid Mvid { @@ -346,7 +357,7 @@ namespace Mono.Cecil { get { #if !PCL if (assembly_resolver == null) - Interlocked.CompareExchange (ref assembly_resolver, new DefaultAssemblyResolver (), null); + Interlocked.CompareExchange (ref assembly_resolver, new AssemblyResolver (), null); #endif return assembly_resolver; @@ -520,12 +531,21 @@ namespace Mono.Cecil { this.architecture = image.Architecture; this.attributes = image.Attributes; this.characteristics = image.Characteristics; - this.fq_name = image.FileName; + this.file_name = image.FileName; this.reader = new MetadataReader (this); } - public bool HasTypeReference (string fullName) + public void Dispose () + { + if (Image != null) + Image.Dispose (); + + if (SymbolReader != null) + SymbolReader.Dispose (); + } + + public bool HasTypeReference (string fullName) { return HasTypeReference (string.Empty, fullName); } @@ -990,14 +1010,14 @@ namespace Mono.Cecil { #if !PCL public void ReadSymbols () { - if (string.IsNullOrEmpty (fq_name)) + if (string.IsNullOrEmpty (file_name)) throw new InvalidOperationException (); var provider = SymbolProvider.GetPlatformReaderProvider (); if (provider == null) throw new InvalidOperationException (); - ReadSymbols (provider.GetSymbolReader (this, fq_name)); + ReadSymbols (provider.GetSymbolReader (this, file_name)); } #endif @@ -1019,9 +1039,19 @@ namespace Mono.Cecil { public static ModuleDefinition ReadModule (string fileName, ReaderParameters parameters) { - using (var stream = GetFileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { - return ReadModule (stream, parameters); + var stream = GetFileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read) as Stream; + + if (parameters.InMemory) { + var memory = new MemoryStream (stream.CanSeek ? (int) stream.Length : 0); + using (stream) + stream.CopyTo (memory); + + memory.Position = 0; + stream = memory; } + + return ReadModule (stream, fileName, parameters); + } static Stream GetFileStream (string fileName, FileMode mode, FileAccess access, FileShare share) @@ -1048,13 +1078,18 @@ namespace Mono.Cecil { public static ModuleDefinition ReadModule (Stream stream, ReaderParameters parameters) { + return ReadModule (stream, "", parameters); + } + + static ModuleDefinition ReadModule (Stream stream, string fileName, ReaderParameters parameters) + { Mixin.CheckStream (stream); if (!stream.CanRead || !stream.CanSeek) throw new ArgumentException (); Mixin.CheckParameters (parameters); return ModuleReader.CreateModule ( - ImageReader.ReadImage (stream), + ImageReader.ReadImage (stream, fileName), parameters); } @@ -1163,6 +1198,16 @@ namespace Mono.Cecil { #endif } +#if !NET_4_0 + public static void CopyTo (this Stream self, Stream target) + { + var buffer = new byte [1024 * 8]; + int read; + while ((read = self.Read (buffer, 0, buffer.Length)) > 0) + target.Write (buffer, 0, read); + } +#endif + public static TargetRuntime ParseRuntime (this string self) { switch (self [1]) { diff --git a/Test/Mono.Cecil.Tests/BaseTestFixture.cs b/Test/Mono.Cecil.Tests/BaseTestFixture.cs index c09fbcb..fb5fd5f 100644 --- a/Test/Mono.Cecil.Tests/BaseTestFixture.cs +++ b/Test/Mono.Cecil.Tests/BaseTestFixture.cs @@ -54,7 +54,7 @@ namespace Mono.Cecil.Tests { internal Image GetResourceImage (string name) { using (var fs = new FileStream (GetAssemblyResourcePath (name, GetType ().Assembly), FileMode.Open, FileAccess.Read)) - return ImageReader.ReadImage (fs); + return ImageReader.ReadImage (fs, fs.Name); } public ModuleDefinition GetCurrentModule () @@ -109,20 +109,20 @@ namespace Mono.Cecil.Tests { static void Run (TestCase testCase) { - var runner = new TestRunner (testCase, TestCaseType.ReadDeferred); - runner.RunTest (); + using (var runner = new TestRunner (testCase, TestCaseType.ReadDeferred)) + runner.RunTest (); - runner = new TestRunner (testCase, TestCaseType.ReadImmediate); - runner.RunTest (); + using (var runner = new TestRunner (testCase, TestCaseType.ReadImmediate)) + runner.RunTest (); if (testCase.ReadOnly) return; - runner = new TestRunner (testCase, TestCaseType.WriteFromDeferred); - runner.RunTest (); + using (var runner = new TestRunner (testCase, TestCaseType.WriteFromDeferred)) + runner.RunTest (); - runner = new TestRunner (testCase, TestCaseType.WriteFromImmediate); - runner.RunTest (); + using (var runner = new TestRunner (testCase, TestCaseType.WriteFromImmediate)) + runner.RunTest (); } } @@ -204,11 +204,14 @@ namespace Mono.Cecil.Tests { } } - class TestRunner { + class TestRunner : IDisposable { readonly TestCase test_case; readonly TestCaseType type; + ModuleDefinition test_module; + DefaultAssemblyResolver test_resolver; + public TestRunner (TestCase testCase, TestCaseType type) { this.test_case = testCase; @@ -263,10 +266,10 @@ namespace Mono.Cecil.Tests { if (test_case.AssemblyResolver != null) return test_case.AssemblyResolver; - var resolver = new DefaultAssemblyResolver (); + test_resolver = new DefaultAssemblyResolver (); var directory = Path.GetDirectoryName (test_case.ModuleLocation); - resolver.AddSearchDirectory (directory); - return resolver; + test_resolver.AddSearchDirectory (directory); + return test_resolver; } ModuleDefinition RoundTrip (string location, ReaderParameters reader_parameters, string folder) @@ -297,8 +300,17 @@ namespace Mono.Cecil.Tests { if (module == null) return; + test_module = module; test_case.Test (module); } + + public void Dispose () + { + test_module.Dispose (); + + if (test_resolver != null) + test_resolver.Dispose (); + } } enum TestCaseType { diff --git a/Test/Mono.Cecil.Tests/CustomAttributesTests.cs b/Test/Mono.Cecil.Tests/CustomAttributesTests.cs index 5af0467..0b4ae44 100644 --- a/Test/Mono.Cecil.Tests/CustomAttributesTests.cs +++ b/Test/Mono.Cecil.Tests/CustomAttributesTests.cs @@ -445,6 +445,8 @@ namespace Mono.Cecil.Tests { Assert.IsNotNull (attribute); Assert.AreEqual ("CaBlob", (string) attribute.ConstructorArguments [0].Value); + + module.Dispose (); } static void AssertCustomAttribute (string expected, CustomAttribute attribute) diff --git a/Test/Mono.Cecil.Tests/Extensions.cs b/Test/Mono.Cecil.Tests/Extensions.cs index 0788d21..ab27e9b 100644 --- a/Test/Mono.Cecil.Tests/Extensions.cs +++ b/Test/Mono.Cecil.Tests/Extensions.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using SR = System.Reflection; @@ -20,7 +21,7 @@ namespace Mono.Cecil.Tests { public static TypeDefinition ToDefinition (this Type self) { - var module = ModuleDefinition.ReadModule (self.Module.FullyQualifiedName); + var module = ModuleDefinition.ReadModule (new MemoryStream (File.ReadAllBytes (self.Module.FullyQualifiedName))); return (TypeDefinition) module.LookupToken (self.MetadataToken); } diff --git a/Test/Mono.Cecil.Tests/ImageReadTests.cs b/Test/Mono.Cecil.Tests/ImageReadTests.cs index 3c89a08..368c760 100644 --- a/Test/Mono.Cecil.Tests/ImageReadTests.cs +++ b/Test/Mono.Cecil.Tests/ImageReadTests.cs @@ -15,77 +15,78 @@ namespace Mono.Cecil.Tests { [Test] public void ImageSections () { - var image = GetResourceImage ("hello.exe"); - - Assert.AreEqual (3, image.Sections.Length); - Assert.AreEqual (".text", image.Sections [0].Name); - Assert.AreEqual (".rsrc", image.Sections [1].Name); - Assert.AreEqual (".reloc", image.Sections [2].Name); + using (var image = GetResourceImage ("hello.exe")) { + Assert.AreEqual (3, image.Sections.Length); + Assert.AreEqual (".text", image.Sections [0].Name); + Assert.AreEqual (".rsrc", image.Sections [1].Name); + Assert.AreEqual (".reloc", image.Sections [2].Name); + } } [Test] public void ImageMetadataVersion () { - var image = GetResourceImage ("hello.exe"); - Assert.AreEqual (TargetRuntime.Net_2_0, image.RuntimeVersion.ParseRuntime ()); + using (var image = GetResourceImage ("hello.exe")) + Assert.AreEqual (TargetRuntime.Net_2_0, image.RuntimeVersion.ParseRuntime ()); - image = GetResourceImage ("hello1.exe"); - Assert.AreEqual (TargetRuntime.Net_1_1, image.RuntimeVersion.ParseRuntime ()); + using (var image = GetResourceImage ("hello1.exe")) + Assert.AreEqual (TargetRuntime.Net_1_1, image.RuntimeVersion.ParseRuntime ()); } [Test] public void ImageModuleKind () { - var image = GetResourceImage ("hello.exe"); - Assert.AreEqual (ModuleKind.Console, image.Kind); + using (var image = GetResourceImage ("hello.exe")) + Assert.AreEqual (ModuleKind.Console, image.Kind); - image = GetResourceImage ("libhello.dll"); - Assert.AreEqual (ModuleKind.Dll, image.Kind); + using (var image = GetResourceImage ("libhello.dll")) + Assert.AreEqual (ModuleKind.Dll, image.Kind); - image = GetResourceImage ("hellow.exe"); - Assert.AreEqual (ModuleKind.Windows, image.Kind); + using (var image = GetResourceImage ("hellow.exe")) + Assert.AreEqual (ModuleKind.Windows, image.Kind); } [Test] public void MetadataHeaps () { - var image = GetResourceImage ("hello.exe"); - - Assert.IsNotNull (image.TableHeap); + using (var image = GetResourceImage ("hello.exe")) { + Assert.IsNotNull (image.TableHeap); - Assert.IsNotNull (image.StringHeap); - Assert.AreEqual (string.Empty, image.StringHeap.Read (0)); - Assert.AreEqual ("<Module>", image.StringHeap.Read (1)); + Assert.IsNotNull (image.StringHeap); + Assert.AreEqual (string.Empty, image.StringHeap.Read (0)); + Assert.AreEqual ("<Module>", image.StringHeap.Read (1)); - Assert.IsNotNull (image.UserStringHeap); - Assert.AreEqual (string.Empty, image.UserStringHeap.Read (0)); - Assert.AreEqual ("Hello Cecil World !", image.UserStringHeap.Read (1)); + Assert.IsNotNull (image.UserStringHeap); + Assert.AreEqual (string.Empty, image.UserStringHeap.Read (0)); + Assert.AreEqual ("Hello Cecil World !", image.UserStringHeap.Read (1)); - Assert.IsNotNull (image.GuidHeap); - Assert.AreEqual (new Guid (), image.GuidHeap.Read (0)); - Assert.AreEqual (new Guid ("C3BC2BD3-2576-4D00-A80E-465B5632415F"), image.GuidHeap.Read (1)); + Assert.IsNotNull (image.GuidHeap); + Assert.AreEqual (new Guid (), image.GuidHeap.Read (0)); + Assert.AreEqual (new Guid ("C3BC2BD3-2576-4D00-A80E-465B5632415F"), image.GuidHeap.Read (1)); - Assert.IsNotNull (image.BlobHeap); - Assert.AreEqual (new byte [0], image.BlobHeap.Read (0)); + Assert.IsNotNull (image.BlobHeap); + Assert.AreEqual (new byte [0], image.BlobHeap.Read (0)); + } } [Test] public void TablesHeap () { - var image = GetResourceImage ("hello.exe"); - var heap = image.TableHeap; - - Assert.IsNotNull (heap); - - Assert.AreEqual (1, heap [Table.Module].Length); - Assert.AreEqual (4, heap [Table.TypeRef].Length); - Assert.AreEqual (2, heap [Table.TypeDef].Length); - Assert.AreEqual (0, heap [Table.Field].Length); - Assert.AreEqual (2, heap [Table.Method].Length); - Assert.AreEqual (4, heap [Table.MemberRef].Length); - Assert.AreEqual (2, heap [Table.CustomAttribute].Length); - Assert.AreEqual (1, heap [Table.Assembly].Length); - Assert.AreEqual (1, heap [Table.AssemblyRef].Length); + using (var image = GetResourceImage ("hello.exe")) { + var heap = image.TableHeap; + + Assert.IsNotNull (heap); + + Assert.AreEqual (1, heap [Table.Module].Length); + Assert.AreEqual (4, heap [Table.TypeRef].Length); + Assert.AreEqual (2, heap [Table.TypeDef].Length); + Assert.AreEqual (0, heap [Table.Field].Length); + Assert.AreEqual (2, heap [Table.Method].Length); + Assert.AreEqual (4, heap [Table.MemberRef].Length); + Assert.AreEqual (2, heap [Table.CustomAttribute].Length); + Assert.AreEqual (1, heap [Table.Assembly].Length); + Assert.AreEqual (1, heap [Table.AssemblyRef].Length); + } } [Test] diff --git a/Test/Mono.Cecil.Tests/ImportCecilTests.cs b/Test/Mono.Cecil.Tests/ImportCecilTests.cs index 92f0cd7..299948f 100644 --- a/Test/Mono.Cecil.Tests/ImportCecilTests.cs +++ b/Test/Mono.Cecil.Tests/ImportCecilTests.cs @@ -214,11 +214,11 @@ namespace Mono.Cecil.Tests { public void ImportMethodOnOpenGeneric () { var generic = typeof (Generic<>).ToDefinition (); - var module = ModuleDefinition.CreateModule ("foo", ModuleKind.Dll); - var method = module.ImportReference (generic.GetMethod ("Method")); - - Assert.AreEqual ("T Mono.Cecil.Tests.ImportCecilTests/Generic`1::Method(T)", method.FullName); + using (var module = ModuleDefinition.CreateModule ("foo", ModuleKind.Dll)) { + var method = module.ImportReference (generic.GetMethod ("Method")); + Assert.AreEqual ("T Mono.Cecil.Tests.ImportCecilTests/Generic`1::Method(T)", method.FullName); + } } public class ContextGeneric1Method2<G1> diff --git a/Test/Mono.Cecil.Tests/ImportReflectionTests.cs b/Test/Mono.Cecil.Tests/ImportReflectionTests.cs index b57f95e..65a1f1a 100644 --- a/Test/Mono.Cecil.Tests/ImportReflectionTests.cs +++ b/Test/Mono.Cecil.Tests/ImportReflectionTests.cs @@ -221,13 +221,13 @@ namespace Mono.Cecil.Tests { [Test] public void ImportGenericTypeDefOrOpen () { - var module = typeof (Foo<>).ToDefinition ().Module; + using (var module = typeof (Foo<>).ToDefinition ().Module) { + var foo_def = module.ImportReference (typeof (Foo<>)); + var foo_open = module.ImportReference (typeof (Foo<>), foo_def); - var foo_def = module.ImportReference (typeof (Foo<>)); - var foo_open = module.ImportReference (typeof (Foo<>), foo_def); - - Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1", foo_def.FullName); - Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1<TFoo>", foo_open.FullName); + Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1", foo_def.FullName); + Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1<TFoo>", foo_open.FullName); + } } [Test] @@ -237,12 +237,12 @@ namespace Mono.Cecil.Tests { var generic_list_foo_open = typeof (Generic<>).MakeGenericType (list_foo); var foo_def = typeof (Foo<>).ToDefinition (); - var module = foo_def.Module; + using (var module = foo_def.Module) { + var generic_foo = module.ImportReference (generic_list_foo_open, foo_def); - var generic_foo = module.ImportReference (generic_list_foo_open, foo_def); - - Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Generic`1<System.Collections.Generic.List`1<TFoo>>", - generic_foo.FullName); + Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Generic`1<System.Collections.Generic.List`1<TFoo>>", + generic_foo.FullName); + } } [Test] @@ -252,12 +252,12 @@ namespace Mono.Cecil.Tests { var generic_foo_open = typeof (Generic<>).MakeGenericType (foo_open); var foo_def = typeof (Foo<>).ToDefinition (); - var module = foo_def.Module; + using (var module = foo_def.Module) { + var generic_foo = module.ImportReference (generic_foo_open, foo_def); - var generic_foo = module.ImportReference (generic_foo_open, foo_def); - - Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Generic`1<Mono.Cecil.Tests.ImportReflectionTests/Foo`1<TFoo>>", - generic_foo.FullName); + Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Generic`1<Mono.Cecil.Tests.ImportReflectionTests/Foo`1<TFoo>>", + generic_foo.FullName); + } } [Test] @@ -267,12 +267,12 @@ namespace Mono.Cecil.Tests { var foo_open_array = foo_open.MakeArrayType (); var foo_def = typeof (Foo<>).ToDefinition (); - var module = foo_def.Module; + using (var module = foo_def.Module) { + var array_foo = module.ImportReference (foo_open_array, foo_def); - var array_foo = module.ImportReference (foo_open_array, foo_def); - - Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1<TFoo>[]", - array_foo.FullName); + Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1<TFoo>[]", + array_foo.FullName); + } } [Test] @@ -283,12 +283,12 @@ namespace Mono.Cecil.Tests { var generic_list_foo_open_field = generic_list_foo_open.GetField ("Field"); var foo_def = typeof (Foo<>).ToDefinition (); - var module = foo_def.Module; + using (var module = foo_def.Module) { + var generic_field = module.ImportReference (generic_list_foo_open_field, foo_def); - var generic_field = module.ImportReference (generic_list_foo_open_field, foo_def); - - Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1<System.Collections.Generic.List`1<TFoo>>::Field", - generic_field.FullName); + Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1<System.Collections.Generic.List`1<TFoo>>::Field", + generic_field.FullName); + } } [Test] @@ -299,36 +299,36 @@ namespace Mono.Cecil.Tests { var generic_list_foo_open_method = generic_list_foo_open.GetMethod ("Method"); var foo_def = typeof (Foo<>).ToDefinition (); - var module = foo_def.Module; + using (var module = foo_def.Module) { + var generic_method = module.ImportReference (generic_list_foo_open_method, foo_def); - var generic_method = module.ImportReference (generic_list_foo_open_method, foo_def); - - Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1<System.Collections.Generic.List`1<TFoo>>::Method(T)", - generic_method.FullName); + Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1<System.Collections.Generic.List`1<TFoo>>::Method(T)", + generic_method.FullName); + } } [Test] public void ImportMethodOnOpenGenericType () { - var module = typeof (Generic<>).ToDefinition ().Module; + using (var module = typeof (Generic<>).ToDefinition ().Module) { + var method = module.ImportReference (typeof (Generic<>).GetMethod ("Method")); - var method = module.ImportReference (typeof (Generic<>).GetMethod ("Method")); - - Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1<T>::Method(T)", method.FullName); + Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1<T>::Method(T)", method.FullName); + } } [Test] public void ImportGenericMethodOnOpenGenericType () { - var module = typeof (Generic<>).ToDefinition ().Module; + using (var module = typeof (Generic<>).ToDefinition ().Module) { + var generic_method = module.ImportReference (typeof (Generic<>).GetMethod ("GenericMethod")); - var generic_method = module.ImportReference (typeof (Generic<>).GetMethod ("GenericMethod")); + Assert.AreEqual ("TS Mono.Cecil.Tests.ImportReflectionTests/Generic`1<T>::GenericMethod(T,TS)", generic_method.FullName); - Assert.AreEqual ("TS Mono.Cecil.Tests.ImportReflectionTests/Generic`1<T>::GenericMethod(T,TS)", generic_method.FullName); + generic_method = module.ImportReference (typeof (Generic<>).GetMethod ("GenericMethod"), generic_method); - generic_method = module.ImportReference (typeof (Generic<>).GetMethod ("GenericMethod"), generic_method); - - Assert.AreEqual ("TS Mono.Cecil.Tests.ImportReflectionTests/Generic`1<T>::GenericMethod<TS>(T,TS)", generic_method.FullName); + Assert.AreEqual ("TS Mono.Cecil.Tests.ImportReflectionTests/Generic`1<T>::GenericMethod<TS>(T,TS)", generic_method.FullName); + } } delegate void Emitter (ModuleDefinition module, MethodBody body); diff --git a/Test/Mono.Cecil.Tests/ModuleTests.cs b/Test/Mono.Cecil.Tests/ModuleTests.cs index 84efb4a..57b6e5b 100644 --- a/Test/Mono.Cecil.Tests/ModuleTests.cs +++ b/Test/Mono.Cecil.Tests/ModuleTests.cs @@ -208,7 +208,7 @@ namespace Mono.Cecil.Tests { public void Win32FileVersion () { TestModule ("libhello.dll", module => { - var version = FileVersionInfo.GetVersionInfo (module.FullyQualifiedName); + var version = FileVersionInfo.GetVersionInfo (module.FileName); Assert.AreEqual ("0.0.0.0", version.FileVersion); }); @@ -225,10 +225,10 @@ namespace Mono.Cecil.Tests { [Test] public void MixedModeModule () { - var module = GetResourceModule ("cppcli.dll"); - - Assert.AreEqual (1, module.ModuleReferences.Count); - Assert.AreEqual (string.Empty, module.ModuleReferences [0].Name); + using (var module = GetResourceModule ("cppcli.dll")) { + Assert.AreEqual (1, module.ModuleReferences.Count); + Assert.AreEqual (string.Empty, module.ModuleReferences [0].Name); + } } [Test] @@ -239,40 +239,28 @@ namespace Mono.Cecil.Tests { } [Test] - public void WriteModuleTwice () - { - var module = GetResourceModule ("iterator.exe"); - - var path = Path.Combine (Path.GetTempPath (), "cecil"); - var file = Path.Combine (path, "iteratorrt.exe"); - - module.Write (file); - module.Write (file); - } - - [Test] public void GetTypeNamespacePlusName () { - var module = GetResourceModule ("moda.netmodule"); - - var type = module.GetType ("Module.A", "Foo"); - Assert.IsNotNull (type); + using (var module = GetResourceModule ("moda.netmodule")) { + var type = module.GetType ("Module.A", "Foo"); + Assert.IsNotNull (type); + } } [Test] public void OpenModuleImmediate () { - var module = GetResourceModule ("hello.exe", ReadingMode.Immediate); - - Assert.AreEqual (ReadingMode.Immediate, module.ReadingMode); + using (var module = GetResourceModule ("hello.exe", ReadingMode.Immediate)) { + Assert.AreEqual (ReadingMode.Immediate, module.ReadingMode); + } } [Test] public void OpenModuleDeferred () { - var module = GetResourceModule ("hello.exe", ReadingMode.Deferred); - - Assert.AreEqual (ReadingMode.Deferred, module.ReadingMode); + using (var module = GetResourceModule ("hello.exe", ReadingMode.Deferred)) { + Assert.AreEqual (ReadingMode.Deferred, module.ReadingMode); + } } } } diff --git a/Test/Mono.Cecil.Tests/ResolveTests.cs b/Test/Mono.Cecil.Tests/ResolveTests.cs index 00bfdd0..aab7d0c 100644 --- a/Test/Mono.Cecil.Tests/ResolveTests.cs +++ b/Test/Mono.Cecil.Tests/ResolveTests.cs @@ -100,7 +100,7 @@ namespace Mono.Cecil.Tests { public void Register (AssemblyDefinition assembly) { this.RegisterAssembly (assembly); - this.AddSearchDirectory (Path.GetDirectoryName (assembly.MainModule.FullyQualifiedName)); + this.AddSearchDirectory (Path.GetDirectoryName (assembly.MainModule.FileName)); } } @@ -113,12 +113,13 @@ namespace Mono.Cecil.Tests { resolver.Register (mma.Assembly); - var current_module = GetCurrentModule (parameters); - var reference = new TypeReference ("Module.A", "Foo", current_module, AssemblyNameReference.Parse (mma.Assembly.FullName), false); + using (var current_module = GetCurrentModule (parameters)) { + var reference = new TypeReference ("Module.A", "Foo", current_module, AssemblyNameReference.Parse (mma.Assembly.FullName), false); - var definition = reference.Resolve (); - Assert.IsNotNull (definition); - Assert.AreEqual ("Module.A.Foo", definition.FullName); + var definition = reference.Resolve (); + Assert.IsNotNull (definition); + Assert.AreEqual ("Module.A.Foo", definition.FullName); + } } [Test] diff --git a/rocks/Mono.Cecil.Rocks/ILParser.cs b/rocks/Mono.Cecil.Rocks/ILParser.cs index e88fe5a..a6b9383 100644 --- a/rocks/Mono.Cecil.Rocks/ILParser.cs +++ b/rocks/Mono.Cecil.Rocks/ILParser.cs @@ -61,8 +61,6 @@ namespace Mono.Cecil.Rocks { var context = CreateContext (method, visitor); var code = context.Code; - code.MoveTo (method.RVA); - var flags = code.ReadByte (); switch (flags & 0x3) { @@ -71,7 +69,7 @@ namespace Mono.Cecil.Rocks { ParseCode (code_size, context); break; case 0x3: // fat - code.position--; + code.Advance (-1); ParseFatMethod (context); break; default: @@ -81,7 +79,7 @@ namespace Mono.Cecil.Rocks { static ParseContext CreateContext (MethodDefinition method, IILVisitor visitor) { - var code = method.Module.Read (method, (_, reader) => new CodeReader (reader.image.MetadataSection, reader)); + var code = method.Module.Read (method, (m, reader) => new CodeReader (method, reader)); return new ParseContext { Code = code, @@ -110,10 +108,10 @@ namespace Mono.Cecil.Rocks { var metadata = context.Metadata; var visitor = context.Visitor; - var start = code.position; + var start = code.Position; var end = start + code_size; - while (code.position < end) { + while (code.Position < end) { var il_opcode = code.ReadByte (); var opcode = il_opcode != 0xfe ? OpCodes.OneByteOpCode [il_opcode] |