diff --git a/Mono.Cecil.20/Mono.Cecil.20.csproj b/Mono.Cecil.20/Mono.Cecil.20.csproj index fa034e72..043c58a1 100644 --- a/Mono.Cecil.20/Mono.Cecil.20.csproj +++ b/Mono.Cecil.20/Mono.Cecil.20.csproj @@ -1,177 +1,20 @@  - - + - Debug - AnyCPU - {D3785D8B-4D85-4546-8763-47FC848C13E0} - Library - Properties + {D68133BD-1E63-496E-9EDE-4FBDBF77B486} Mono.Cecil - Mono.Cecil.20 - v2.0 - 512 - - + Mono.Cecil - - true - full - false - ..\bin\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - \ No newline at end of file + + + diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Code.cs b/Mono.Cecil.20/Mono.Cecil.Cil/Code.cs similarity index 69% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Code.cs rename to Mono.Cecil.20/Mono.Cecil.Cil/Code.cs index fa88b63d..cd929fcc 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Code.cs +++ b/Mono.Cecil.20/Mono.Cecil.Cil/Code.cs @@ -1,29 +1,11 @@ // -// Code.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // namespace Mono.Cecil.Cil { diff --git a/Mono.Cecil.20/Mono.Cecil.Cil/CodeReader.cs b/Mono.Cecil.20/Mono.Cecil.Cil/CodeReader.cs new file mode 100644 index 00000000..73cf923c --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Cil/CodeReader.cs @@ -0,0 +1,645 @@ +// +// 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 Mono.Cecil.PE; +using Mono.Collections.Generic; + +using RVA = System.UInt32; + +namespace Mono.Cecil.Cil { + + sealed class CodeReader : BinaryStreamReader { + + readonly internal MetadataReader reader; + + int start; + + MethodDefinition method; + MethodBody body; + + int Offset { + get { return Position - start; } + } + + public CodeReader (MetadataReader reader) + : base (reader.image.Stream.value) + { + this.reader = reader; + } + + public int MoveTo (MethodDefinition method) + { + this.method = method; + this.reader.context = method; + var position = this.Position; + this.Position = (int) reader.image.ResolveVirtualAddress ((uint) method.RVA); + return position; + } + + void MoveBackTo (int position) + { + this.reader.context = null; + this.Position = position; + } + + public MethodBody ReadMethodBody (MethodDefinition method) + { + var position = MoveTo (method); + this.body = new MethodBody (method); + + ReadMethodBody (); + + MoveBackTo (position); + return this.body; + } + + void ReadMethodBody () + { + var flags = ReadByte (); + switch (flags & 0x3) { + case 0x2: // tiny + body.code_size = flags >> 2; + body.MaxStackSize = 8; + ReadCode (); + break; + case 0x3: // fat + Advance (-1); + ReadFatMethod (); + break; + default: + throw new InvalidOperationException (); + } + + var symbol_reader = reader.module.symbol_reader; + + //if (symbol_reader != null && method.debug_info == null) + if (symbol_reader != null) + method.debug_info = symbol_reader.Read (method); + else + method.debug_info = null; + + if (method.debug_info != null) + ReadDebugInfo (); + } + + void ReadDebugInfo () + { + if (method.debug_info.sequence_points != null) + 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) + { + var start_instruction = GetInstruction (scope.Start.Offset); + if (start_instruction != null) + scope.Start = new InstructionOffset (start_instruction); + + var end_instruction = GetInstruction (scope.End.Offset); + scope.End = end_instruction != null + ? new InstructionOffset (end_instruction) + : new InstructionOffset (); + + if (!scope.variables.IsNullOrEmpty ()) { + for (int i = 0; i < scope.variables.Count; i++) { + var variable_info = scope.variables [i]; + var variable = GetVariable (variable_info.Index); + if (variable != null) + variable_info.index = new VariableIndex (variable); + } + } + + if (!scope.scopes.IsNullOrEmpty ()) + ReadScopes (scope.scopes); + } + + void ReadFatMethod () + { + var flags = ReadUInt16 (); + body.max_stack_size = ReadUInt16 (); + body.code_size = (int) ReadUInt32 (); + body.local_var_token = new MetadataToken (ReadUInt32 ()); + body.init_locals = (flags & 0x10) != 0; + + if (body.local_var_token.RID != 0) + body.variables = ReadVariables (body.local_var_token); + + ReadCode (); + + if ((flags & 0x8) != 0) + ReadSection (); + } + + public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token) + { + var position = reader.position; + var variables = reader.ReadVariables (local_var_token); + reader.position = position; + + return variables; + } + + void ReadCode () + { + start = Position; + var code_size = body.code_size; + + if (code_size < 0 || Length <= (uint) (code_size + Position)) + code_size = 0; + + var end = start + code_size; + var instructions = body.instructions = new InstructionCollection (method, (code_size + 1) / 2); + + while (Position < end) { + var offset = Position - start; + var opcode = ReadOpCode (); + var current = new Instruction (method, offset, opcode); + + if (opcode.OperandType != OperandType.InlineNone) + current.operand = ReadOperand (current); + + instructions.Add (current); + } + + ResolveBranches (instructions); + } + + OpCode ReadOpCode () + { + var il_opcode = ReadByte (); + return il_opcode != 0xfe + ? OpCodes.OneByteOpCode [il_opcode] + : OpCodes.TwoBytesOpCode [ReadByte ()]; + } + + object ReadOperand (Instruction instruction) + { + switch (instruction.opcode.OperandType) { + case OperandType.InlineSwitch: + var length = ReadInt32 (); + var base_offset = Offset + (4 * length); + var branches = new int [length]; + for (int i = 0; i < length; i++) + branches [i] = base_offset + ReadInt32 (); + return branches; + case OperandType.ShortInlineBrTarget: + return ReadSByte () + Offset; + case OperandType.InlineBrTarget: + return ReadInt32 () + Offset; + case OperandType.ShortInlineI: + if (instruction.opcode == OpCodes.Ldc_I4_S) + return ReadSByte (); + + return ReadByte (); + case OperandType.InlineI: + return ReadInt32 (); + case OperandType.ShortInlineR: + return ReadSingle (); + case OperandType.InlineR: + return ReadDouble (); + case OperandType.InlineI8: + return ReadInt64 (); + case OperandType.ShortInlineVar: + return GetVariable (ReadByte ()); + case OperandType.InlineVar: + return GetVariable (ReadUInt16 ()); + case OperandType.ShortInlineArg: + return GetParameter (ReadByte ()); + case OperandType.InlineArg: + return GetParameter (ReadUInt16 ()); + case OperandType.InlineSig: + return GetCallSite (ReadToken ()); + case OperandType.InlineString: + return GetString (ReadToken ()); + case OperandType.InlineTok: + case OperandType.InlineType: + case OperandType.InlineMethod: + case OperandType.InlineField: + return reader.LookupToken (ReadToken ()); + default: + throw new NotSupportedException (); + } + } + + public string GetString (MetadataToken token) + { + return reader.image.UserStringHeap.Read (token.RID); + } + + public ParameterDefinition GetParameter (int index) + { + return body.GetParameter (index); + } + + public VariableDefinition GetVariable (int index) + { + return body.GetVariable (index); + } + + public CallSite GetCallSite (MetadataToken token) + { + return reader.ReadCallSite (token); + } + + void ResolveBranches (Collection instructions) + { + var items = instructions.items; + var size = instructions.size; + + for (int i = 0; i < size; i++) { + var instruction = items [i]; + switch (instruction.opcode.OperandType) { + case OperandType.ShortInlineBrTarget: + case OperandType.InlineBrTarget: + instruction.operand = GetInstruction ((int) instruction.operand); + break; + case OperandType.InlineSwitch: + var offsets = (int []) instruction.operand; + var branches = new Instruction [offsets.Length]; + for (int j = 0; j < offsets.Length; j++) + branches [j] = GetInstruction (offsets [j]); + + instruction.operand = branches; + break; + } + } + } + + Instruction GetInstruction (int offset) + { + return GetInstruction (body.Instructions, offset); + } + + static Instruction GetInstruction (Collection instructions, int offset) + { + var size = instructions.size; + var items = instructions.items; + if (offset < 0 || offset > items [size - 1].offset) + return null; + + int min = 0; + int max = size - 1; + while (min <= max) { + int mid = min + ((max - min) / 2); + var instruction = items [mid]; + var instruction_offset = instruction.offset; + + if (offset == instruction_offset) + return instruction; + + if (offset < instruction_offset) + max = mid - 1; + else + min = mid + 1; + } + + return null; + } + + void ReadSection () + { + Align (4); + + const byte fat_format = 0x40; + const byte more_sects = 0x80; + + var flags = ReadByte (); + if ((flags & fat_format) == 0) + ReadSmallSection (); + else + ReadFatSection (); + + if ((flags & more_sects) != 0) + ReadSection (); + } + + void ReadSmallSection () + { + var count = ReadByte () / 12; + Advance (2); + + ReadExceptionHandlers ( + count, + () => (int) ReadUInt16 (), + () => (int) ReadByte ()); + } + + void ReadFatSection () + { + Advance (-1); + var count = (ReadInt32 () >> 8) / 24; + + ReadExceptionHandlers ( + count, + ReadInt32, + ReadInt32); + } + + // inline ? + void ReadExceptionHandlers (int count, Func read_entry, Func read_length) + { + for (int i = 0; i < count; i++) { + var handler = new ExceptionHandler ( + (ExceptionHandlerType) (read_entry () & 0x7)); + + handler.TryStart = GetInstruction (read_entry ()); + handler.TryEnd = GetInstruction (handler.TryStart.Offset + read_length ()); + + handler.HandlerStart = GetInstruction (read_entry ()); + handler.HandlerEnd = GetInstruction (handler.HandlerStart.Offset + read_length ()); + + ReadExceptionHandlerSpecific (handler); + + this.body.ExceptionHandlers.Add (handler); + } + } + + void ReadExceptionHandlerSpecific (ExceptionHandler handler) + { + switch (handler.HandlerType) { + case ExceptionHandlerType.Catch: + handler.CatchType = (TypeReference) reader.LookupToken (ReadToken ()); + break; + case ExceptionHandlerType.Filter: + handler.FilterStart = GetInstruction (ReadInt32 ()); + break; + default: + Advance (4); + break; + } + } + + public MetadataToken ReadToken () + { + return new MetadataToken (ReadUInt32 ()); + } + +#if !READ_ONLY + + public ByteBuffer PatchRawMethodBody (MethodDefinition method, CodeWriter writer, out int code_size, out MetadataToken local_var_token) + { + var position = MoveTo (method); + + var buffer = new ByteBuffer (); + + var flags = ReadByte (); + + switch (flags & 0x3) { + case 0x2: // tiny + buffer.WriteByte (flags); + local_var_token = MetadataToken.Zero; + code_size = flags >> 2; + PatchRawCode (buffer, code_size, writer); + break; + case 0x3: // fat + Advance (-1); + PatchRawFatMethod (buffer, writer, out code_size, out local_var_token); + break; + default: + throw new NotSupportedException (); + } + + MoveBackTo (position); + + return buffer; + } + + void PatchRawFatMethod (ByteBuffer buffer, CodeWriter writer, out int code_size, out MetadataToken local_var_token) + { + var flags = ReadUInt16 (); + buffer.WriteUInt16 (flags); + buffer.WriteUInt16 (ReadUInt16 ()); + code_size = ReadInt32 (); + buffer.WriteInt32 (code_size); + local_var_token = ReadToken (); + + if (local_var_token.RID > 0) { + var variables = ReadVariables (local_var_token); + buffer.WriteUInt32 (variables != null + ? writer.GetStandAloneSignature (variables).ToUInt32 () + : 0); + } else + buffer.WriteUInt32 (0); + + PatchRawCode (buffer, code_size, writer); + + if ((flags & 0x8) != 0) + PatchRawSection (buffer, writer.metadata); + } + + void PatchRawCode (ByteBuffer buffer, int code_size, CodeWriter writer) + { + var metadata = writer.metadata; + buffer.WriteBytes (ReadBytes (code_size)); + var end = buffer.position; + buffer.position -= code_size; + + while (buffer.position < end) { + OpCode opcode; + var il_opcode = buffer.ReadByte (); + if (il_opcode != 0xfe) { + opcode = OpCodes.OneByteOpCode [il_opcode]; + } else { + var il_opcode2 = buffer.ReadByte (); + opcode = OpCodes.TwoBytesOpCode [il_opcode2]; + } + + switch (opcode.OperandType) { + case OperandType.ShortInlineI: + case OperandType.ShortInlineBrTarget: + case OperandType.ShortInlineVar: + case OperandType.ShortInlineArg: + buffer.position += 1; + break; + case OperandType.InlineVar: + case OperandType.InlineArg: + buffer.position += 2; + break; + case OperandType.InlineBrTarget: + case OperandType.ShortInlineR: + case OperandType.InlineI: + buffer.position += 4; + break; + case OperandType.InlineI8: + case OperandType.InlineR: + buffer.position += 8; + break; + case OperandType.InlineSwitch: + var length = buffer.ReadInt32 (); + buffer.position += length * 4; + break; + case OperandType.InlineString: + var @string = GetString (new MetadataToken (buffer.ReadUInt32 ())); + buffer.position -= 4; + buffer.WriteUInt32 ( + new MetadataToken ( + TokenType.String, + metadata.user_string_heap.GetStringIndex (@string)).ToUInt32 ()); + break; + case OperandType.InlineSig: + var call_site = GetCallSite (new MetadataToken (buffer.ReadUInt32 ())); + buffer.position -= 4; + buffer.WriteUInt32 (writer.GetStandAloneSignature (call_site).ToUInt32 ()); + break; + case OperandType.InlineTok: + case OperandType.InlineType: + case OperandType.InlineMethod: + case OperandType.InlineField: + var provider = reader.LookupToken (new MetadataToken (buffer.ReadUInt32 ())); + buffer.position -= 4; + buffer.WriteUInt32 (metadata.LookupToken (provider).ToUInt32 ()); + break; + } + } + } + + void PatchRawSection (ByteBuffer buffer, MetadataBuilder metadata) + { + var position = Position; + Align (4); + buffer.WriteBytes (Position - position); + + const byte fat_format = 0x40; + const byte more_sects = 0x80; + + var flags = ReadByte (); + if ((flags & fat_format) == 0) { + buffer.WriteByte (flags); + PatchRawSmallSection (buffer, metadata); + } else + PatchRawFatSection (buffer, metadata); + + if ((flags & more_sects) != 0) + PatchRawSection (buffer, metadata); + } + + void PatchRawSmallSection (ByteBuffer buffer, MetadataBuilder metadata) + { + var length = ReadByte (); + buffer.WriteByte (length); + Advance (2); + + buffer.WriteUInt16 (0); + + var count = length / 12; + + PatchRawExceptionHandlers (buffer, metadata, count, false); + } + + void PatchRawFatSection (ByteBuffer buffer, MetadataBuilder metadata) + { + Advance (-1); + var length = ReadInt32 (); + buffer.WriteInt32 (length); + + var count = (length >> 8) / 24; + + PatchRawExceptionHandlers (buffer, metadata, count, true); + } + + void PatchRawExceptionHandlers (ByteBuffer buffer, MetadataBuilder metadata, int count, bool fat_entry) + { + const int fat_entry_size = 16; + const int small_entry_size = 6; + + for (int i = 0; i < count; i++) { + ExceptionHandlerType handler_type; + if (fat_entry) { + var type = ReadUInt32 (); + handler_type = (ExceptionHandlerType) (type & 0x7); + buffer.WriteUInt32 (type); + } else { + var type = ReadUInt16 (); + handler_type = (ExceptionHandlerType) (type & 0x7); + buffer.WriteUInt16 (type); + } + + buffer.WriteBytes (ReadBytes (fat_entry ? fat_entry_size : small_entry_size)); + + switch (handler_type) { + case ExceptionHandlerType.Catch: + var exception = reader.LookupToken (ReadToken ()); + buffer.WriteUInt32 (metadata.LookupToken (exception).ToUInt32 ()); + break; + default: + buffer.WriteUInt32 (ReadUInt32 ()); + break; + } + } + } + +#endif + + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.Cil/CodeWriter.cs b/Mono.Cecil.20/Mono.Cecil.Cil/CodeWriter.cs new file mode 100644 index 00000000..2003f104 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Cil/CodeWriter.cs @@ -0,0 +1,659 @@ +// +// 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 Mono.Collections.Generic; + +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; + +using RVA = System.UInt32; + +#if !READ_ONLY + +namespace Mono.Cecil.Cil { + + sealed class CodeWriter : ByteBuffer { + + readonly RVA code_base; + internal readonly MetadataBuilder metadata; + readonly Dictionary standalone_signatures; + readonly Dictionary tiny_method_bodies; + + MethodBody body; + + public CodeWriter (MetadataBuilder metadata) + : base (0) + { + this.code_base = metadata.text_map.GetNextRVA (TextSegment.CLIHeader); + this.metadata = metadata; + this.standalone_signatures = new Dictionary (); + this.tiny_method_bodies = new Dictionary (new ByteBufferEqualityComparer ()); + } + + public RVA WriteMethodBody (MethodDefinition method) + { + RVA rva; + + if (IsUnresolved (method)) { + if (method.rva == 0) + return 0; + + rva = WriteUnresolvedMethodBody (method); + } else { + if (IsEmptyMethodBody (method.Body)) + return 0; + + rva = WriteResolvedMethodBody (method); + } + + return rva; + } + + static bool IsEmptyMethodBody (MethodBody body) + { + return body.instructions.IsNullOrEmpty () + && body.variables.IsNullOrEmpty (); + } + + static bool IsUnresolved (MethodDefinition method) + { + return method.HasBody && method.HasImage && method.body == null; + } + + RVA WriteUnresolvedMethodBody (MethodDefinition method) + { + var code_reader = metadata.module.reader.code; + + int code_size; + MetadataToken local_var_token; + var raw_body = code_reader.PatchRawMethodBody (method, this, out code_size, out local_var_token); + var fat_header = (raw_body.buffer [0] & 0x3) == 0x3; + if (fat_header) + Align (4); + + var rva = BeginMethod (); + + if (fat_header || !GetOrMapTinyMethodBody (raw_body, ref rva)) { + WriteBytes (raw_body); + } + + if (method.debug_info == null) + return rva; + + var symbol_writer = metadata.symbol_writer; + 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); + } + + return rva; + } + + RVA WriteResolvedMethodBody(MethodDefinition method) + { + RVA rva; + + body = method.Body; + ComputeHeader (); + if (RequiresFatHeader ()) { + Align (4); + rva = BeginMethod (); + WriteFatHeader (); + WriteInstructions (); + + if (body.HasExceptionHandlers) + WriteExceptionHandlers (); + } else { + rva = BeginMethod (); + WriteByte ((byte) (0x2 | (body.CodeSize << 2))); // tiny + WriteInstructions (); + + var start_position = (int) (rva - code_base); + var body_size = position - start_position; + var body_bytes = new byte [body_size]; + + Array.Copy (buffer, start_position, body_bytes, 0, body_size); + + if (GetOrMapTinyMethodBody (new ByteBuffer (body_bytes), ref rva)) + position = start_position; + } + + var symbol_writer = metadata.symbol_writer; + 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); + } + + return rva; + } + + bool GetOrMapTinyMethodBody (ByteBuffer body, ref RVA rva) + { + RVA existing_rva; + if (tiny_method_bodies.TryGetValue (body, out existing_rva)) { + rva = existing_rva; + return true; + } + + tiny_method_bodies.Add (body, rva); + return false; + } + + void WriteFatHeader () + { + var body = this.body; + byte flags = 0x3; // fat + if (body.InitLocals) + flags |= 0x10; // init locals + if (body.HasExceptionHandlers) + flags |= 0x8; // more sections + + WriteByte (flags); + WriteByte (0x30); + WriteInt16 ((short) body.max_stack_size); + WriteInt32 (body.code_size); + body.local_var_token = body.HasVariables + ? GetStandAloneSignature (body.Variables) + : MetadataToken.Zero; + WriteMetadataToken (body.local_var_token); + } + + void WriteInstructions () + { + var instructions = body.Instructions; + var items = instructions.items; + var size = instructions.size; + + for (int i = 0; i < size; i++) { + var instruction = items [i]; + WriteOpCode (instruction.opcode); + WriteOperand (instruction); + } + } + + void WriteOpCode (OpCode opcode) + { + if (opcode.Size == 1) { + WriteByte (opcode.Op2); + } else { + WriteByte (opcode.Op1); + WriteByte (opcode.Op2); + } + } + + void WriteOperand (Instruction instruction) + { + var opcode = instruction.opcode; + var operand_type = opcode.OperandType; + if (operand_type == OperandType.InlineNone) + return; + + var operand = instruction.operand; + if (operand == null && !(operand_type == OperandType.InlineBrTarget || operand_type == OperandType.ShortInlineBrTarget)) { + throw new ArgumentException (); + } + + switch (operand_type) { + case OperandType.InlineSwitch: { + var targets = (Instruction []) operand; + WriteInt32 (targets.Length); + var diff = instruction.Offset + opcode.Size + (4 * (targets.Length + 1)); + for (int i = 0; i < targets.Length; i++) + WriteInt32 (GetTargetOffset (targets [i]) - diff); + break; + } + case OperandType.ShortInlineBrTarget: { + var target = (Instruction) operand; + var offset = target != null ? GetTargetOffset (target) : body.code_size; + WriteSByte ((sbyte) (offset - (instruction.Offset + opcode.Size + 1))); + break; + } + case OperandType.InlineBrTarget: { + var target = (Instruction) operand; + var offset = target != null ? GetTargetOffset (target) : body.code_size; + WriteInt32 (offset - (instruction.Offset + opcode.Size + 4)); + break; + } + case OperandType.ShortInlineVar: + WriteByte ((byte) GetVariableIndex ((VariableDefinition) operand)); + break; + case OperandType.ShortInlineArg: + WriteByte ((byte) GetParameterIndex ((ParameterDefinition) operand)); + break; + case OperandType.InlineVar: + WriteInt16 ((short) GetVariableIndex ((VariableDefinition) operand)); + break; + case OperandType.InlineArg: + WriteInt16 ((short) GetParameterIndex ((ParameterDefinition) operand)); + break; + case OperandType.InlineSig: + WriteMetadataToken (GetStandAloneSignature ((CallSite) operand)); + break; + case OperandType.ShortInlineI: + if (opcode == OpCodes.Ldc_I4_S) + WriteSByte ((sbyte) operand); + else + WriteByte ((byte) operand); + break; + case OperandType.InlineI: + WriteInt32 ((int) operand); + break; + case OperandType.InlineI8: + WriteInt64 ((long) operand); + break; + case OperandType.ShortInlineR: + WriteSingle ((float) operand); + break; + case OperandType.InlineR: + WriteDouble ((double) operand); + break; + case OperandType.InlineString: + WriteMetadataToken ( + new MetadataToken ( + TokenType.String, + GetUserStringIndex ((string) operand))); + break; + case OperandType.InlineType: + case OperandType.InlineField: + case OperandType.InlineMethod: + case OperandType.InlineTok: + WriteMetadataToken (metadata.LookupToken ((IMetadataTokenProvider) operand)); + break; + default: + throw new ArgumentException (); + } + } + + int GetTargetOffset (Instruction instruction) + { + if (instruction == null) { + var last = body.instructions [body.instructions.size - 1]; + return last.offset + last.GetSize (); + } + + return instruction.offset; + } + + uint GetUserStringIndex (string @string) + { + if (@string == null) + return 0; + + return metadata.user_string_heap.GetStringIndex (@string); + } + + static int GetVariableIndex (VariableDefinition variable) + { + return variable.Index; + } + + int GetParameterIndex (ParameterDefinition parameter) + { + if (body.method.HasThis) { + if (parameter == body.this_parameter) + return 0; + + return parameter.Index + 1; + } + + return parameter.Index; + } + + bool RequiresFatHeader () + { + var body = this.body; + return body.CodeSize >= 64 + || body.InitLocals + || body.HasVariables + || body.HasExceptionHandlers + || body.MaxStackSize > 8; + } + + void ComputeHeader () + { + int offset = 0; + var instructions = body.instructions; + var items = instructions.items; + var count = instructions.size; + var stack_size = 0; + var max_stack = 0; + Dictionary stack_sizes = null; + + if (body.HasExceptionHandlers) + ComputeExceptionHandlerStackSize (ref stack_sizes); + + for (int i = 0; i < count; i++) { + var instruction = items [i]; + instruction.offset = offset; + offset += instruction.GetSize (); + + ComputeStackSize (instruction, ref stack_sizes, ref stack_size, ref max_stack); + } + + body.code_size = offset; + body.max_stack_size = max_stack; + } + + void ComputeExceptionHandlerStackSize (ref Dictionary stack_sizes) + { + var exception_handlers = body.ExceptionHandlers; + + for (int i = 0; i < exception_handlers.Count; i++) { + var exception_handler = exception_handlers [i]; + + switch (exception_handler.HandlerType) { + case ExceptionHandlerType.Catch: + AddExceptionStackSize (exception_handler.HandlerStart, ref stack_sizes); + break; + case ExceptionHandlerType.Filter: + AddExceptionStackSize (exception_handler.FilterStart, ref stack_sizes); + AddExceptionStackSize (exception_handler.HandlerStart, ref stack_sizes); + break; + } + } + } + + static void AddExceptionStackSize (Instruction handler_start, ref Dictionary stack_sizes) + { + if (handler_start == null) + return; + + if (stack_sizes == null) + stack_sizes = new Dictionary (); + + stack_sizes [handler_start] = 1; + } + + static void ComputeStackSize (Instruction instruction, ref Dictionary stack_sizes, ref int stack_size, ref int max_stack) + { + int computed_size; + if (stack_sizes != null && stack_sizes.TryGetValue (instruction, out computed_size)) + stack_size = computed_size; + + max_stack = System.Math.Max (max_stack, stack_size); + ComputeStackDelta (instruction, ref stack_size); + max_stack = System.Math.Max (max_stack, stack_size); + + CopyBranchStackSize (instruction, ref stack_sizes, stack_size); + ComputeStackSize (instruction, ref stack_size); + } + + static void CopyBranchStackSize (Instruction instruction, ref Dictionary stack_sizes, int stack_size) + { + if (stack_size == 0) + return; + + switch (instruction.opcode.OperandType) { + case OperandType.ShortInlineBrTarget: + case OperandType.InlineBrTarget: + CopyBranchStackSize (ref stack_sizes, (Instruction) instruction.operand, stack_size); + break; + case OperandType.InlineSwitch: + var targets = (Instruction []) instruction.operand; + for (int i = 0; i < targets.Length; i++) + CopyBranchStackSize (ref stack_sizes, targets [i], stack_size); + break; + } + } + + static void CopyBranchStackSize (ref Dictionary stack_sizes, Instruction target, int stack_size) + { + if (stack_sizes == null) + stack_sizes = new Dictionary (); + + int branch_stack_size = stack_size; + + int computed_size; + if (stack_sizes.TryGetValue (target, out computed_size)) + branch_stack_size = System.Math.Max (branch_stack_size, computed_size); + + stack_sizes [target] = branch_stack_size; + } + + static void ComputeStackSize (Instruction instruction, ref int stack_size) + { + switch (instruction.opcode.FlowControl) { + case FlowControl.Branch: + case FlowControl.Break: + case FlowControl.Throw: + case FlowControl.Return: + stack_size = 0; + break; + } + } + + static void ComputeStackDelta (Instruction instruction, ref int stack_size) + { + switch (instruction.opcode.FlowControl) { + case FlowControl.Call: { + var method = (IMethodSignature) instruction.operand; + // pop 'this' argument + if (method.HasImplicitThis() && instruction.opcode.Code != Code.Newobj) + stack_size--; + // pop normal arguments + if (method.HasParameters) + stack_size -= method.Parameters.Count; + // pop function pointer + if (instruction.opcode.Code == Code.Calli) + stack_size--; + // push return value + if (method.ReturnType.etype != ElementType.Void || instruction.opcode.Code == Code.Newobj) + stack_size++; + break; + } + default: + ComputePopDelta (instruction.opcode.StackBehaviourPop, ref stack_size); + ComputePushDelta (instruction.opcode.StackBehaviourPush, ref stack_size); + break; + } + } + + static void ComputePopDelta (StackBehaviour pop_behavior, ref int stack_size) + { + switch (pop_behavior) { + case StackBehaviour.Popi: + case StackBehaviour.Popref: + case StackBehaviour.Pop1: + stack_size--; + break; + case StackBehaviour.Pop1_pop1: + case StackBehaviour.Popi_pop1: + case StackBehaviour.Popi_popi: + case StackBehaviour.Popi_popi8: + case StackBehaviour.Popi_popr4: + case StackBehaviour.Popi_popr8: + case StackBehaviour.Popref_pop1: + case StackBehaviour.Popref_popi: + stack_size -= 2; + break; + case StackBehaviour.Popi_popi_popi: + case StackBehaviour.Popref_popi_popi: + case StackBehaviour.Popref_popi_popi8: + case StackBehaviour.Popref_popi_popr4: + case StackBehaviour.Popref_popi_popr8: + case StackBehaviour.Popref_popi_popref: + stack_size -= 3; + break; + case StackBehaviour.PopAll: + stack_size = 0; + break; + } + } + + static void ComputePushDelta (StackBehaviour push_behaviour, ref int stack_size) + { + switch (push_behaviour) { + case StackBehaviour.Push1: + case StackBehaviour.Pushi: + case StackBehaviour.Pushi8: + case StackBehaviour.Pushr4: + case StackBehaviour.Pushr8: + case StackBehaviour.Pushref: + stack_size++; + break; + case StackBehaviour.Push1_push1: + stack_size += 2; + break; + } + } + + void WriteExceptionHandlers () + { + Align (4); + + var handlers = body.ExceptionHandlers; + + if (handlers.Count < 0x15 && !RequiresFatSection (handlers)) + WriteSmallSection (handlers); + else + WriteFatSection (handlers); + } + + static bool RequiresFatSection (Collection handlers) + { + for (int i = 0; i < handlers.Count; i++) { + var handler = handlers [i]; + + if (IsFatRange (handler.TryStart, handler.TryEnd)) + return true; + + if (IsFatRange (handler.HandlerStart, handler.HandlerEnd)) + return true; + + if (handler.HandlerType == ExceptionHandlerType.Filter + && IsFatRange (handler.FilterStart, handler.HandlerStart)) + return true; + } + + return false; + } + + static bool IsFatRange (Instruction start, Instruction end) + { + if (start == null) + throw new ArgumentException (); + + if (end == null) + return true; + + return end.Offset - start.Offset > 255 || start.Offset > 65535; + } + + void WriteSmallSection (Collection handlers) + { + const byte eh_table = 0x1; + + WriteByte (eh_table); + WriteByte ((byte) (handlers.Count * 12 + 4)); + WriteBytes (2); + + WriteExceptionHandlers ( + handlers, + i => WriteUInt16 ((ushort) i), + i => WriteByte ((byte) i)); + } + + void WriteFatSection (Collection handlers) + { + const byte eh_table = 0x1; + const byte fat_format = 0x40; + + WriteByte (eh_table | fat_format); + + int size = handlers.Count * 24 + 4; + WriteByte ((byte) (size & 0xff)); + WriteByte ((byte) ((size >> 8) & 0xff)); + WriteByte ((byte) ((size >> 16) & 0xff)); + + WriteExceptionHandlers (handlers, WriteInt32, WriteInt32); + } + + void WriteExceptionHandlers (Collection handlers, Action write_entry, Action write_length) + { + for (int i = 0; i < handlers.Count; i++) { + var handler = handlers [i]; + + write_entry ((int) handler.HandlerType); + + write_entry (handler.TryStart.Offset); + write_length (GetTargetOffset (handler.TryEnd) - handler.TryStart.Offset); + + write_entry (handler.HandlerStart.Offset); + write_length (GetTargetOffset (handler.HandlerEnd) - handler.HandlerStart.Offset); + + WriteExceptionHandlerSpecific (handler); + } + } + + void WriteExceptionHandlerSpecific (ExceptionHandler handler) + { + switch (handler.HandlerType) { + case ExceptionHandlerType.Catch: + WriteMetadataToken (metadata.LookupToken (handler.CatchType)); + break; + case ExceptionHandlerType.Filter: + WriteInt32 (handler.FilterStart.Offset); + break; + default: + WriteInt32 (0); + break; + } + } + + public MetadataToken GetStandAloneSignature (Collection variables) + { + var signature = metadata.GetLocalVariableBlobIndex (variables); + + return GetStandAloneSignatureToken (signature); + } + + public MetadataToken GetStandAloneSignature (CallSite call_site) + { + var signature = metadata.GetCallSiteBlobIndex (call_site); + var token = GetStandAloneSignatureToken (signature); + call_site.MetadataToken = token; + return token; + } + + MetadataToken GetStandAloneSignatureToken (uint signature) + { + MetadataToken token; + if (standalone_signatures.TryGetValue (signature, out token)) + return token; + + token = new MetadataToken (TokenType.Signature, metadata.AddStandAloneSignature (signature)); + standalone_signatures.Add (signature, token); + return token; + } + + RVA BeginMethod () + { + return (RVA)(code_base + position); + } + + void WriteMetadataToken (MetadataToken token) + { + WriteUInt32 (token.ToUInt32 ()); + } + + void Align (int align) + { + align--; + WriteBytes (((position + align) & ~align) - position); + } + } +} + +#endif diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Document.cs b/Mono.Cecil.20/Mono.Cecil.Cil/Document.cs similarity index 53% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Document.cs rename to Mono.Cecil.20/Mono.Cecil.Cil/Document.cs index 1dbdc447..2c2d21e1 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Document.cs +++ b/Mono.Cecil.20/Mono.Cecil.Cil/Document.cs @@ -1,29 +1,11 @@ // -// Document.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; @@ -39,6 +21,7 @@ public enum DocumentHashAlgorithm { None, MD5, SHA1, + SHA256, } public enum DocumentLanguage { @@ -62,7 +45,7 @@ public enum DocumentLanguageVendor { Microsoft, } - public sealed class Document { + public sealed class Document : DebugInformation { string url; @@ -107,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.20/MonoCecil/Mono.Cecil.Cil/ExceptionHandler.cs b/Mono.Cecil.20/Mono.Cecil.Cil/ExceptionHandler.cs similarity index 52% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ExceptionHandler.cs rename to Mono.Cecil.20/Mono.Cecil.Cil/ExceptionHandler.cs index c61ff235..6bdb1aa3 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ExceptionHandler.cs +++ b/Mono.Cecil.20/Mono.Cecil.Cil/ExceptionHandler.cs @@ -1,29 +1,11 @@ // -// ExceptionHandler.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // namespace Mono.Cecil.Cil { diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ILProcessor.cs b/Mono.Cecil.20/Mono.Cecil.Cil/ILProcessor.cs similarity index 69% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ILProcessor.cs rename to Mono.Cecil.20/Mono.Cecil.Cil/ILProcessor.cs index 64368e62..0e81fdea 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ILProcessor.cs +++ b/Mono.Cecil.20/Mono.Cecil.Cil/ILProcessor.cs @@ -1,29 +1,11 @@ // -// ILProcessor.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; @@ -49,94 +31,94 @@ internal ILProcessor (MethodBody body) public Instruction Create (OpCode opcode) { - return Instruction.Create (opcode); + return Instruction.Create (body.method, opcode); } public Instruction Create (OpCode opcode, TypeReference type) { - return Instruction.Create (opcode, type); + return Instruction.Create (body.method, opcode, type); } public Instruction Create (OpCode opcode, CallSite site) { - return Instruction.Create (opcode, site); + return Instruction.Create (body.method, opcode, site); } public Instruction Create (OpCode opcode, MethodReference method) { - return Instruction.Create (opcode, method); + return Instruction.Create (body.method, opcode, method); } public Instruction Create (OpCode opcode, FieldReference field) { - return Instruction.Create (opcode, field); + return Instruction.Create (body.method, opcode, field); } public Instruction Create (OpCode opcode, string value) { - return Instruction.Create (opcode, value); + return Instruction.Create (body.method, opcode, value); } public Instruction Create (OpCode opcode, sbyte value) { - return Instruction.Create (opcode, value); + return Instruction.Create (body.method, opcode, value); } public Instruction Create (OpCode opcode, byte value) { if (opcode.OperandType == OperandType.ShortInlineVar) - return Instruction.Create (opcode, body.Variables [value]); + return Instruction.Create (body.method, opcode, body.Variables [value]); if (opcode.OperandType == OperandType.ShortInlineArg) - return Instruction.Create (opcode, Mixin.GetParameter (body,value)); + return Instruction.Create (body.method, opcode, body.GetParameter (value)); - return Instruction.Create (opcode, value); + return Instruction.Create (body.method, opcode, value); } public Instruction Create (OpCode opcode, int value) { if (opcode.OperandType == OperandType.InlineVar) - return Instruction.Create (opcode, body.Variables [value]); + return Instruction.Create (body.method, opcode, body.Variables [value]); if (opcode.OperandType == OperandType.InlineArg) - return Instruction.Create (opcode, Mixin.GetParameter (body,value)); + return Instruction.Create (body.method, opcode, body.GetParameter (value)); - return Instruction.Create (opcode, value); + return Instruction.Create (body.method, opcode, value); } public Instruction Create (OpCode opcode, long value) { - return Instruction.Create (opcode, value); + return Instruction.Create (body.method, opcode, value); } public Instruction Create (OpCode opcode, float value) { - return Instruction.Create (opcode, value); + return Instruction.Create (body.method, opcode, value); } public Instruction Create (OpCode opcode, double value) { - return Instruction.Create (opcode, value); + return Instruction.Create (body.method, opcode, value); } public Instruction Create (OpCode opcode, Instruction target) { - return Instruction.Create (opcode, target); + return Instruction.Create (body.method, opcode, target); } public Instruction Create (OpCode opcode, Instruction [] targets) { - return Instruction.Create (opcode, targets); + return Instruction.Create (body.method, opcode, targets); } public Instruction Create (OpCode opcode, VariableDefinition variable) { - return Instruction.Create (opcode, variable); + return Instruction.Create (body.method, opcode, variable); } public Instruction Create (OpCode opcode, ParameterDefinition parameter) { - return Instruction.Create (opcode, parameter); + return Instruction.Create (body.method, opcode, parameter); } public void Emit (OpCode opcode) diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Instruction.cs b/Mono.Cecil.20/Mono.Cecil.Cil/Instruction.cs similarity index 63% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Instruction.cs rename to Mono.Cecil.20/Mono.Cecil.Cil/Instruction.cs index c28d4c99..0225f50c 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Instruction.cs +++ b/Mono.Cecil.20/Mono.Cecil.Cil/Instruction.cs @@ -1,29 +1,11 @@ // -// Instruction.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; @@ -40,7 +22,9 @@ public sealed class Instruction { internal Instruction previous; internal Instruction next; - SequencePoint sequence_point; + internal MethodDefinition method; + + SequencePoint sequence_point; public int Offset { get { return offset; } @@ -67,21 +51,29 @@ public Instruction Next { set { next = value; } } - public SequencePoint SequencePoint { - get { return sequence_point; } - set { sequence_point = value; } + public SequencePoint SequencePoint + { + get { + if (sequence_point == null) + { + sequence_point = method.DebugInformation.GetSequencePoint(this); + } + return sequence_point; + } } - internal Instruction (int offset, OpCode opCode) + internal Instruction (MethodDefinition method,int offset, OpCode opCode) { this.offset = offset; this.opcode = opCode; + this.method = method; } - internal Instruction (OpCode opcode, object operand) + internal Instruction (MethodDefinition method,OpCode opcode, object operand) { this.opcode = opcode; this.operand = operand; + this.method = method; } public int GetSize () @@ -164,15 +156,15 @@ static void AppendLabel (StringBuilder builder, Instruction instruction) builder.Append (instruction.offset.ToString ("x4")); } - public static Instruction Create (OpCode opcode) + public static Instruction Create (MethodDefinition method, OpCode opcode) { if (opcode.OperandType != OperandType.InlineNone) throw new ArgumentException ("opcode"); - return new Instruction (opcode, null); + return new Instruction (method, opcode, null); } - public static Instruction Create (OpCode opcode, TypeReference type) + public static Instruction Create (MethodDefinition method, OpCode opcode, TypeReference type) { if (type == null) throw new ArgumentNullException ("type"); @@ -180,20 +172,20 @@ public static Instruction Create (OpCode opcode, TypeReference type) opcode.OperandType != OperandType.InlineTok) throw new ArgumentException ("opcode"); - return new Instruction (opcode, type); + return new Instruction (method, opcode, type); } - public static Instruction Create (OpCode opcode, CallSite site) + public static Instruction Create (MethodDefinition method, OpCode opcode, CallSite site) { if (site == null) throw new ArgumentNullException ("site"); if (opcode.Code != Code.Calli) throw new ArgumentException ("code"); - return new Instruction (opcode, site); + return new Instruction (method, opcode, site); } - public static Instruction Create (OpCode opcode, MethodReference method) + public static Instruction Create (MethodDefinition method_, OpCode opcode, MethodReference method) { if (method == null) throw new ArgumentNullException ("method"); @@ -201,10 +193,10 @@ public static Instruction Create (OpCode opcode, MethodReference method) opcode.OperandType != OperandType.InlineTok) throw new ArgumentException ("opcode"); - return new Instruction (opcode, method); + return new Instruction (method_,opcode, method); } - public static Instruction Create (OpCode opcode, FieldReference field) + public static Instruction Create (MethodDefinition method, OpCode opcode, FieldReference field) { if (field == null) throw new ArgumentNullException ("field"); @@ -212,70 +204,70 @@ public static Instruction Create (OpCode opcode, FieldReference field) opcode.OperandType != OperandType.InlineTok) throw new ArgumentException ("opcode"); - return new Instruction (opcode, field); + return new Instruction (method, opcode, field); } - public static Instruction Create (OpCode opcode, string value) + public static Instruction Create (MethodDefinition method, OpCode opcode, string value) { if (value == null) throw new ArgumentNullException ("value"); if (opcode.OperandType != OperandType.InlineString) throw new ArgumentException ("opcode"); - return new Instruction (opcode, value); + return new Instruction (method, opcode, value); } - public static Instruction Create (OpCode opcode, sbyte value) + public static Instruction Create (MethodDefinition method, OpCode opcode, sbyte value) { if (opcode.OperandType != OperandType.ShortInlineI && opcode != OpCodes.Ldc_I4_S) throw new ArgumentException ("opcode"); - return new Instruction (opcode, value); + return new Instruction (method, opcode, value); } - public static Instruction Create (OpCode opcode, byte value) + public static Instruction Create (MethodDefinition method, OpCode opcode, byte value) { if (opcode.OperandType != OperandType.ShortInlineI || opcode == OpCodes.Ldc_I4_S) throw new ArgumentException ("opcode"); - return new Instruction (opcode, value); + return new Instruction (method, opcode, value); } - public static Instruction Create (OpCode opcode, int value) + public static Instruction Create (MethodDefinition method, OpCode opcode, int value) { if (opcode.OperandType != OperandType.InlineI) throw new ArgumentException ("opcode"); - return new Instruction (opcode, value); + return new Instruction (method, opcode, value); } - public static Instruction Create (OpCode opcode, long value) + public static Instruction Create (MethodDefinition method, OpCode opcode, long value) { if (opcode.OperandType != OperandType.InlineI8) throw new ArgumentException ("opcode"); - return new Instruction (opcode, value); + return new Instruction (method, opcode, value); } - public static Instruction Create (OpCode opcode, float value) + public static Instruction Create (MethodDefinition method, OpCode opcode, float value) { if (opcode.OperandType != OperandType.ShortInlineR) throw new ArgumentException ("opcode"); - return new Instruction (opcode, value); + return new Instruction (method, opcode, value); } - public static Instruction Create (OpCode opcode, double value) + public static Instruction Create (MethodDefinition method, OpCode opcode, double value) { if (opcode.OperandType != OperandType.InlineR) throw new ArgumentException ("opcode"); - return new Instruction (opcode, value); + return new Instruction (method, opcode, value); } - public static Instruction Create (OpCode opcode, Instruction target) + public static Instruction Create (MethodDefinition method, OpCode opcode, Instruction target) { if (target == null) throw new ArgumentNullException ("target"); @@ -283,20 +275,20 @@ public static Instruction Create (OpCode opcode, Instruction target) opcode.OperandType != OperandType.ShortInlineBrTarget) throw new ArgumentException ("opcode"); - return new Instruction (opcode, target); + return new Instruction (method, opcode, target); } - public static Instruction Create (OpCode opcode, Instruction [] targets) + public static Instruction Create (MethodDefinition method, OpCode opcode, Instruction [] targets) { if (targets == null) throw new ArgumentNullException ("targets"); if (opcode.OperandType != OperandType.InlineSwitch) throw new ArgumentException ("opcode"); - return new Instruction (opcode, targets); + return new Instruction (method, opcode, targets); } - public static Instruction Create (OpCode opcode, VariableDefinition variable) + public static Instruction Create (MethodDefinition method, OpCode opcode, VariableDefinition variable) { if (variable == null) throw new ArgumentNullException ("variable"); @@ -304,10 +296,10 @@ public static Instruction Create (OpCode opcode, VariableDefinition variable) opcode.OperandType != OperandType.InlineVar) throw new ArgumentException ("opcode"); - return new Instruction (opcode, variable); + return new Instruction (method, opcode, variable); } - public static Instruction Create (OpCode opcode, ParameterDefinition parameter) + public static Instruction Create (MethodDefinition method, OpCode opcode, ParameterDefinition parameter) { if (parameter == null) throw new ArgumentNullException ("parameter"); @@ -315,7 +307,7 @@ public static Instruction Create (OpCode opcode, ParameterDefinition parameter) opcode.OperandType != OperandType.InlineArg) throw new ArgumentException ("opcode"); - return new Instruction (opcode, parameter); + return new Instruction (method, opcode, parameter); } } } diff --git a/Mono.Cecil.20/Mono.Cecil.Cil/MethodBody.cs b/Mono.Cecil.20/Mono.Cecil.Cil/MethodBody.cs new file mode 100644 index 00000000..eb8baf5b --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Cil/MethodBody.cs @@ -0,0 +1,248 @@ +// +// 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.Threading; + +using Mono.Collections.Generic; + +namespace Mono.Cecil.Cil { + + public sealed class MethodBody { + + readonly internal MethodDefinition method; + + internal ParameterDefinition this_parameter; + internal int max_stack_size; + internal int code_size; + internal bool init_locals; + internal MetadataToken local_var_token; + + internal Collection instructions; + internal Collection exceptions; + internal Collection variables; + + public MethodDefinition Method { + get { return method; } + } + + public int MaxStackSize { + get { return max_stack_size; } + set { max_stack_size = value; } + } + + public int CodeSize { + get { return code_size; } + } + + public bool InitLocals { + get { return init_locals; } + set { init_locals = value; } + } + + public MetadataToken LocalVarToken { + get { return local_var_token; } + set { local_var_token = value; } + } + + public Collection Instructions { + get { return instructions ?? (instructions = new InstructionCollection (method)); } + } + + public bool HasExceptionHandlers { + get { return !exceptions.IsNullOrEmpty (); } + } + + public Collection ExceptionHandlers { + get { return exceptions ?? (exceptions = new Collection ()); } + } + + public bool HasVariables { + get { return !variables.IsNullOrEmpty (); } + } + + public Collection Variables { + get { return variables ?? (variables = new VariableDefinitionCollection ()); } + } + + public ParameterDefinition ThisParameter { + get { + if (method == null || method.DeclaringType == null) + throw new NotSupportedException (); + + if (!method.HasThis) + return null; + + if (this_parameter == null) + Interlocked.CompareExchange (ref this_parameter, CreateThisParameter (method), null); + + return this_parameter; + } + } + + static ParameterDefinition CreateThisParameter (MethodDefinition method) + { + var parameter_type = method.DeclaringType as TypeReference; + + if (parameter_type.HasGenericParameters) { + var instance = new GenericInstanceType (parameter_type); + for (int i = 0; i < parameter_type.GenericParameters.Count; i++) + instance.GenericArguments.Add (parameter_type.GenericParameters [i]); + + parameter_type = instance; + + } + + if (parameter_type.IsValueType || parameter_type.IsPrimitive) + parameter_type = new ByReferenceType (parameter_type); + + return new ParameterDefinition (parameter_type, method); + } + + public MethodBody (MethodDefinition method) + { + this.method = method; + } + + public ILProcessor GetILProcessor () + { + return new ILProcessor (this); + } + } + + sealed class VariableDefinitionCollection : Collection { + + internal VariableDefinitionCollection () + { + } + + internal VariableDefinitionCollection (int capacity) + : base (capacity) + { + } + + protected override void OnAdd (VariableDefinition item, int index) + { + item.index = index; + } + + protected override void OnInsert (VariableDefinition item, int index) + { + item.index = index; + + for (int i = index; i < size; i++) + items [i].index = i + 1; + } + + protected override void OnSet (VariableDefinition item, int index) + { + item.index = index; + } + + protected override void OnRemove (VariableDefinition item, int index) + { + item.index = -1; + + for (int i = index + 1; i < size; i++) + items [i].index = i - 1; + } + } + + class InstructionCollection : Collection { + + readonly MethodDefinition method; + + internal InstructionCollection (MethodDefinition method) + { + this.method = method; + } + + internal InstructionCollection (MethodDefinition method, int capacity) + : base (capacity) + { + this.method = method; + } + + protected override void OnAdd (Instruction item, int index) + { + if (index == 0) + return; + + var previous = items [index - 1]; + previous.next = item; + item.previous = previous; + } + + protected override void OnInsert (Instruction item, int index) + { + if (size == 0) + return; + + var current = items [index]; + if (current == null) { + var last = items [index - 1]; + last.next = item; + item.previous = last; + return; + } + + var previous = current.previous; + if (previous != null) { + previous.next = item; + item.previous = previous; + } + + current.previous = item; + item.next = current; + } + + protected override void OnSet (Instruction item, int index) + { + var current = items [index]; + + item.previous = current.previous; + item.next = current.next; + + current.previous = null; + current.next = null; + } + + protected override void OnRemove (Instruction item, int index) + { + var previous = item.previous; + if (previous != null) + previous.next = item.next; + + var next = item.next; + if (next != null) + next.previous = item.previous; + + RemoveSequencePoint (item); + + item.previous = null; + item.next = null; + } + + void RemoveSequencePoint (Instruction instruction) + { + var debug_info = method.debug_info; + if (debug_info == null || !debug_info.HasSequencePoints) + return; + + var sequence_points = debug_info.sequence_points; + for (int i = 0; i < sequence_points.Count; i++) { + if (sequence_points [i].Offset == instruction.offset) { + sequence_points.RemoveAt (i); + return; + } + } + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCode.cs b/Mono.Cecil.20/Mono.Cecil.Cil/OpCode.cs similarity index 91% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCode.cs rename to Mono.Cecil.20/Mono.Cecil.Cil/OpCode.cs index 1a144213..81ab0e12 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCode.cs +++ b/Mono.Cecil.20/Mono.Cecil.Cil/OpCode.cs @@ -1,31 +1,15 @@ // -// OpCode.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // +using System; + namespace Mono.Cecil.Cil { public enum FlowControl { @@ -104,7 +88,7 @@ public enum StackBehaviour { Varpush, } - public struct OpCode { + public struct OpCode : IEquatable { readonly byte op1; readonly byte op2; diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCodes.cs b/Mono.Cecil.20/Mono.Cecil.Cil/OpCodes.cs similarity index 98% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCodes.cs rename to Mono.Cecil.20/Mono.Cecil.Cil/OpCodes.cs index 85712ec8..ba0468d3 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCodes.cs +++ b/Mono.Cecil.20/Mono.Cecil.Cil/OpCodes.cs @@ -1,29 +1,11 @@ // -// OpCodes.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // namespace Mono.Cecil.Cil { diff --git a/Mono.Cecil.20/Mono.Cecil.Cil/PortablePdb.cs b/Mono.Cecil.20/Mono.Cecil.Cil/PortablePdb.cs new file mode 100644 index 00000000..717249e9 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Cil/PortablePdb.cs @@ -0,0 +1,611 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; + +using 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); + Mixin.CheckFileName (fileName); + + var file = File.OpenRead (Mixin.GetPdbFileName (fileName)); + return GetSymbolReader (module, Disposable.Owned (file as Stream), file.Name); + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + + return GetSymbolReader (module, Disposable.NotOwned (symbolStream), symbolStream.GetFileName ()); + } + + ISymbolReader GetSymbolReader (ModuleDefinition module, Disposable symbolStream, string fileName) + { + return new PortablePdbReader (ImageReader.ReadPortablePdb (symbolStream, fileName), module); + } + } + + public sealed class PortablePdbReader : ISymbolReader { + + readonly Image image; + readonly ModuleDefinition module; + readonly MetadataReader reader; + readonly MetadataReader debug_reader; + + bool IsEmbedded { get { return reader.image == debug_reader.image; } } + + internal PortablePdbReader (Image image, ModuleDefinition module) + { + this.image = image; + this.module = module; + this.reader = module.reader; + this.debug_reader = new MetadataReader (image, module, this.reader); + } + +#if !READ_ONLY + public ISymbolWriterProvider GetWriterProvider () + { + return new PortablePdbWriterProvider (); + } +#endif + + public bool ProcessDebugHeader (ImageDebugHeader header) + { + if (image == module.Image) + return true; + + var entry = header.GetCodeViewEntry (); + if (entry == null) + return false; + + var data = entry.Data; + + if (data.Length < 24) + return false; + + var magic = ReadInt32 (data, 0); + if (magic != 0x53445352) + return false; + + var buffer = new byte [16]; + Buffer.BlockCopy (data, 4, buffer, 0, 16); + + var module_guid = new Guid (buffer); + + Buffer.BlockCopy (image.PdbHeap.Id, 0, buffer, 0, 16); + + var pdb_guid = new Guid (buffer); + + if (module_guid != pdb_guid) + return false; + + ReadModule (); + return true; + } + + static int ReadInt32 (byte [] bytes, int start) + { + return (bytes [start] + | (bytes [start + 1] << 8) + | (bytes [start + 2] << 16) + | (bytes [start + 3] << 24)); + } + + void ReadModule () + { + module.custom_infos = debug_reader.GetCustomDebugInformation (module); + } + + public MethodDebugInformation Read (MethodDefinition method) + { + var info = new MethodDebugInformation (method); + ReadSequencePoints (info); + ReadScope (info); + ReadStateMachineKickOffMethod (info); + ReadCustomDebugInformations (info); + return info; + } + + void ReadSequencePoints (MethodDebugInformation method_info) + { + method_info.sequence_points = debug_reader.ReadSequencePoints (method_info.method); + } + + void ReadScope (MethodDebugInformation method_info) + { + method_info.scope = debug_reader.ReadScope (method_info.method); + } + + void ReadStateMachineKickOffMethod (MethodDebugInformation method_info) + { + method_info.kickoff_method = debug_reader.ReadStateMachineKickoffMethod (method_info.method); + } + + void ReadCustomDebugInformations (MethodDebugInformation info) + { + info.method.custom_infos = debug_reader.GetCustomDebugInformation (info.method); + } + + public void Dispose () + { + if (IsEmbedded) + return; + + image.Dispose (); + } + } + + public sealed class EmbeddedPortablePdbReaderProvider : ISymbolReaderProvider { + + public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + var header = module.GetDebugHeader (); + var entry = header.GetEmbeddedPortablePdbEntry (); + if (entry == null) + throw new InvalidOperationException (); + + return new EmbeddedPortablePdbReader ( + (PortablePdbReader) new PortablePdbReaderProvider ().GetSymbolReader (module, GetPortablePdbStream (entry))); + } + + static Stream GetPortablePdbStream (ImageDebugHeaderEntry entry) + { + var compressed_stream = new MemoryStream (entry.Data); + var reader = new BinaryStreamReader (compressed_stream); + reader.ReadInt32 (); // signature + var length = reader.ReadInt32 (); + var decompressed_stream = new MemoryStream (length); + + using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true)) + deflate_stream.CopyTo (decompressed_stream); + + return decompressed_stream; + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + throw new NotSupportedException (); + } + } + + public sealed class EmbeddedPortablePdbReader : ISymbolReader + { + private readonly PortablePdbReader reader; + + internal EmbeddedPortablePdbReader (PortablePdbReader reader) + { + if (reader == null) + throw new ArgumentNullException (); + + this.reader = reader; + } + +#if !READ_ONLY + public ISymbolWriterProvider GetWriterProvider () + { + return new EmbeddedPortablePdbWriterProvider (); + } +#endif + public bool ProcessDebugHeader (ImageDebugHeader header) + { + return reader.ProcessDebugHeader (header); + } + + public MethodDebugInformation Read (MethodDefinition method) + { + return reader.Read (method); + } + + public void Dispose () + { + reader.Dispose (); + } + } + + +#if !READ_ONLY + + public sealed class PortablePdbWriterProvider : ISymbolWriterProvider + { + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + var file = File.OpenWrite (Mixin.GetPdbFileName (fileName)); + return GetSymbolWriter (module, Disposable.Owned (file as Stream)); + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + + return GetSymbolWriter (module, Disposable.NotOwned (symbolStream)); + } + + ISymbolWriter GetSymbolWriter (ModuleDefinition module, Disposable stream) + { + var metadata = new MetadataBuilder (module, this); + var writer = ImageWriter.CreateDebugWriter (module, metadata, stream); + + return new PortablePdbWriter (metadata, module, writer); + } + } + + interface IMetadataSymbolWriter : ISymbolWriter { + void SetMetadata (MetadataBuilder metadata); + void WriteModule (); + } + + public sealed class PortablePdbWriter : ISymbolWriter, IMetadataSymbolWriter { + + readonly MetadataBuilder pdb_metadata; + readonly ModuleDefinition module; + readonly ImageWriter writer; + + MetadataBuilder module_metadata; + + bool IsEmbedded { get { return writer == null; } } + + internal PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module) + { + this.pdb_metadata = pdb_metadata; + this.module = module; + } + + internal PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module, ImageWriter writer) + : this (pdb_metadata, module) + { + this.writer = writer; + } + + void IMetadataSymbolWriter.SetMetadata (MetadataBuilder metadata) + { + this.module_metadata = metadata; + + if (module_metadata != pdb_metadata) + this.pdb_metadata.metadata_builder = metadata; + } + + void IMetadataSymbolWriter.WriteModule () + { + pdb_metadata.AddCustomDebugInformations (module); + } + + public ISymbolReaderProvider GetReaderProvider () + { + return new PortablePdbReaderProvider (); + } + + public ImageDebugHeader GetDebugHeader () + { + if (IsEmbedded) + return new ImageDebugHeader (); + + var directory = new ImageDebugDirectory () { + MajorVersion = 256, + MinorVersion = 20557, + Type = ImageDebugType.CodeView, + TimeDateStamp = (int) module.timestamp, + }; + + var buffer = new ByteBuffer (); + // RSDS + buffer.WriteUInt32 (0x53445352); + // Module ID + buffer.WriteBytes (module.Mvid.ToByteArray ()); + // PDB Age + buffer.WriteUInt32 (1); + // PDB Path + var filename = writer.BaseStream.GetFileName (); + if (!string.IsNullOrEmpty (filename)) + filename = Path.GetFileName (filename); + + buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes (filename)); + buffer.WriteByte (0); + + var data = new byte [buffer.length]; + Buffer.BlockCopy (buffer.buffer, 0, data, 0, buffer.length); + directory.SizeOfData = data.Length; + + return new ImageDebugHeader (new ImageDebugHeaderEntry (directory, data)); + } + + public void Write (MethodDebugInformation info) + { + CheckMethodDebugInformationTable (); + + pdb_metadata.AddMethodDebugInformation (info); + } + + void CheckMethodDebugInformationTable () + { + var mdi = pdb_metadata.table_heap.GetTable (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; + + WritePdbFile (); + } + + void WritePdbFile () + { + WritePdbHeap (); + + WriteTableHeap (); + + writer.BuildMetadataTextMap (); + writer.WriteMetadataHeader (); + writer.WriteMetadata (); + + writer.Flush (); + writer.stream.Dispose (); + } + + void WritePdbHeap () + { + var pdb_heap = pdb_metadata.pdb_heap; + + pdb_heap.WriteBytes (module.Mvid.ToByteArray ()); + pdb_heap.WriteUInt32 (module_metadata.timestamp); + + pdb_heap.WriteUInt32 (module_metadata.entry_point.ToUInt32 ()); + + var table_heap = module_metadata.table_heap; + var tables = table_heap.tables; + + ulong valid = 0; + for (int i = 0; i < tables.Length; i++) { + if (tables [i] == null || tables [i].Length == 0) + continue; + + valid |= (1UL << i); + } + + pdb_heap.WriteUInt64 (valid); + + for (int i = 0; i < tables.Length; i++) { + if (tables [i] == null || tables [i].Length == 0) + continue; + + pdb_heap.WriteUInt32 ((uint) tables [i].Length); + } + } + + void WriteTableHeap () + { + pdb_metadata.table_heap.string_offsets = pdb_metadata.string_heap.WriteStrings (); + pdb_metadata.table_heap.ComputeTableInformations (); + pdb_metadata.table_heap.WriteTableHeap (); + } + } + + public sealed class EmbeddedPortablePdbWriterProvider : ISymbolWriterProvider { + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + var stream = new MemoryStream (); + var pdb_writer = (PortablePdbWriter) new PortablePdbWriterProvider ().GetSymbolWriter (module, stream); + return new EmbeddedPortablePdbWriter (stream, pdb_writer); + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + throw new NotSupportedException (); + } + } + + public sealed class EmbeddedPortablePdbWriter : ISymbolWriter, IMetadataSymbolWriter { + + readonly Stream stream; + readonly PortablePdbWriter writer; + + internal EmbeddedPortablePdbWriter (Stream stream, PortablePdbWriter writer) + { + this.stream = stream; + this.writer = writer; + } + + public ISymbolReaderProvider GetReaderProvider () + { + return new EmbeddedPortablePdbReaderProvider (); + } + + public ImageDebugHeader GetDebugHeader () + { + writer.Dispose (); + + var directory = new ImageDebugDirectory { + Type = ImageDebugType.EmbeddedPortablePdb, + }; + + var data = new MemoryStream (); + + var w = new BinaryStreamWriter (data); + w.WriteByte (0x4d); + w.WriteByte (0x50); + w.WriteByte (0x44); + w.WriteByte (0x42); + + w.WriteInt32 ((int) stream.Length); + + stream.Position = 0; + + using (var compress_stream = new DeflateStream (data, CompressionMode.Compress, leaveOpen: true)) + stream.CopyTo (compress_stream); + + directory.SizeOfData = (int) data.Length; + + return new ImageDebugHeader (new [] { + writer.GetDebugHeader ().Entries [0], + new ImageDebugHeaderEntry (directory, data.ToArray ()) + }); + } + + public void Write (MethodDebugInformation info) + { + writer.Write (info); + } + + public void Dispose () + { + } + + void IMetadataSymbolWriter.SetMetadata (MetadataBuilder metadata) + { + ((IMetadataSymbolWriter) writer).SetMetadata (metadata); + } + + void IMetadataSymbolWriter.WriteModule () + { + ((IMetadataSymbolWriter) writer).WriteModule (); + } + } + +#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 ("63a08714-fc37-11d2-904c-00c04fa302a1")); + AddMapping (DocumentLanguage.Cpp, new Guid ("3a12d0b7-c26c-11d0-b442-00a0244a1dd2")); + AddMapping (DocumentLanguage.CSharp, new Guid ("3f5162f8-07c6-11d3-9053-00c04fa302a1")); + AddMapping (DocumentLanguage.Basic, new Guid ("3a12d0b8-c26c-11d0-b442-00a0244a1dd2")); + AddMapping (DocumentLanguage.Java, new Guid ("3a12d0b4-c26c-11d0-b442-00a0244a1dd2")); + AddMapping (DocumentLanguage.Cobol, new Guid ("af046cd1-d0e1-11d2-977c-00a0c9b4d50c")); + AddMapping (DocumentLanguage.Pascal, new Guid ("af046cd2-d0e1-11d2-977c-00a0c9b4d50c")); + AddMapping (DocumentLanguage.Cil, new Guid ("af046cd3-d0e1-11d2-977c-00a0c9b4d50c")); + AddMapping (DocumentLanguage.JScript, new Guid ("3a12d0b6-c26c-11d0-b442-00a0244a1dd2")); + AddMapping (DocumentLanguage.Smc, new Guid ("0d9b9f7b-6611-11d3-bd2a-0000f80849bd")); + AddMapping (DocumentLanguage.MCpp, new Guid ("4b35fde8-07c6-11d3-9053-00c04fa302a1")); + AddMapping (DocumentLanguage.FSharp, new Guid ("ab4f38c9-b6e6-43ba-be3b-58080b2ccce3")); + } + + static void AddMapping (DocumentLanguage language, Guid guid) + { + guid_language.Add (guid, language); + language_guid.Add (language, guid); + } + + static readonly Guid type_text = new Guid ("5a869d0b-6611-11d3-bd2a-0000f80849bd"); + + public static DocumentType ToType (this Guid guid) + { + if (guid == type_text) + return DocumentType.Text; + + return DocumentType.Other; + } + + public static Guid ToGuid (this DocumentType type) + { + if (type == DocumentType.Text) + return type_text; + + return new Guid (); + } + + static readonly Guid hash_md5 = new Guid ("406ea660-64cf-4c82-b6f0-42d48172a799"); + static readonly Guid hash_sha1 = new Guid ("ff1816ec-aa5e-4d10-87f7-6f4963833460"); + static readonly Guid hash_sha256 = new Guid ("8829d00f-11b8-4213-878b-770e8597ac16"); + + public static DocumentHashAlgorithm ToHashAlgorithm (this Guid guid) + { + if (guid == hash_md5) + return DocumentHashAlgorithm.MD5; + + if (guid == hash_sha1) + return DocumentHashAlgorithm.SHA1; + + if (guid == hash_sha256) + return DocumentHashAlgorithm.SHA256; + + return DocumentHashAlgorithm.None; + } + + public static Guid ToGuid (this DocumentHashAlgorithm hash_algo) + { + if (hash_algo == DocumentHashAlgorithm.MD5) + return hash_md5; + + if (hash_algo == DocumentHashAlgorithm.SHA1) + return hash_sha1; + + return new Guid (); + } + + public static DocumentLanguage ToLanguage (this Guid guid) + { + DocumentLanguage language; + if (!guid_language.TryGetValue (guid, out language)) + return DocumentLanguage.Other; + + return language; + } + + public static Guid ToGuid (this DocumentLanguage language) + { + Guid guid; + if (!language_guid.TryGetValue (language, out guid)) + return new Guid (); + + return guid; + } + + static readonly Guid vendor_ms = new Guid ("994b45c4-e6e9-11d2-903f-00c04fa302a1"); + + public static DocumentLanguageVendor ToVendor (this Guid guid) + { + if (guid == vendor_ms) + return DocumentLanguageVendor.Microsoft; + + return DocumentLanguageVendor.Other; + } + + public static Guid ToGuid (this DocumentLanguageVendor vendor) + { + if (vendor == DocumentLanguageVendor.Microsoft) + return vendor_ms; + + return new Guid (); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.Cil/SequencePoint.cs b/Mono.Cecil.20/Mono.Cecil.Cil/SequencePoint.cs new file mode 100644 index 00000000..725d307a --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Cil/SequencePoint.cs @@ -0,0 +1,76 @@ +// +// 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; + +namespace Mono.Cecil.Cil { + + public sealed class SequencePoint { + + internal InstructionOffset offset; + Document document; + + int start_line; + int start_column; + int end_line; + int end_column; + + public int Offset { + get { return offset.Offset; } + } + + public int StartLine { + get { return start_line; } + set { start_line = value; } + } + + public int StartColumn { + get { return start_column; } + set { start_column = value; } + } + + public int EndLine { + get { return end_line; } + set { end_line = value; } + } + + public int EndColumn { + get { return end_column; } + set { end_column = value; } + } + + public bool IsHidden { + get { return start_line == 0xfeefee && start_line == end_line; } + } + + public Document Document { + get { return document; } + set { document = value; } + } + + 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.20/Mono.Cecil.Cil/Symbols.cs b/Mono.Cecil.20/Mono.Cecil.Cil/Symbols.cs new file mode 100644 index 00000000..85c5334d --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Cil/Symbols.cs @@ -0,0 +1,1010 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +using SR = System.Reflection; + +using Mono.Collections.Generic; +using Mono.Cecil.Cil; + +namespace Mono.Cecil.Cil { + + [StructLayout (LayoutKind.Sequential)] + public struct ImageDebugDirectory { + public const int Size = 28; + + public int Characteristics; + public int TimeDateStamp; + public short MajorVersion; + public short MinorVersion; + public ImageDebugType Type; + public int SizeOfData; + public int AddressOfRawData; + public int PointerToRawData; + } + + public enum ImageDebugType { + CodeView = 2, + Deterministic = 16, + EmbeddedPortablePdb = 17, + } + + public sealed class ImageDebugHeader { + + readonly ImageDebugHeaderEntry [] entries; + + public bool HasEntries { + get { return !entries.IsNullOrEmpty (); } + } + + public ImageDebugHeaderEntry [] Entries { + get { return entries; } + } + + public ImageDebugHeader (ImageDebugHeaderEntry [] entries) + { + this.entries = entries ?? Empty.Array; + } + + public ImageDebugHeader () + : this (Empty.Array) + { + } + + public ImageDebugHeader (ImageDebugHeaderEntry entry) + : this (new [] { entry }) + { + } + } + + public sealed class ImageDebugHeaderEntry { + + ImageDebugDirectory directory; + readonly byte [] data; + + public ImageDebugDirectory Directory { + get { return directory; } + internal set { directory = value; } + } + + public byte [] Data { + get { return data; } + } + + public ImageDebugHeaderEntry (ImageDebugDirectory directory, byte [] data) + { + this.directory = directory; + this.data = data ?? Empty.Array; + } + } + + public sealed class ScopeDebugInformation : DebugInformation { + + internal InstructionOffset start; + internal InstructionOffset end; + internal ImportDebugInformation import; + internal Collection scopes; + internal Collection variables; + internal Collection constants; + + public InstructionOffset Start { + get { return start; } + set { start = value; } + } + + public InstructionOffset End { + get { return end; } + set { end = value; } + } + + public ImportDebugInformation Import { + get { return import; } + set { import = value; } + } + + public bool HasScopes { + get { return !scopes.IsNullOrEmpty (); } + } + + public Collection 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 bool TryGetName (VariableDefinition variable, out string name) + { + name = null; + if (variables == null || variables.Count == 0) + return false; + + for (int i = 0; i < variables.Count; i++) { + if (variables [i].Index == variable.Index) { + name = variables [i].Name; + return true; + } + } + + return false; + } + } + + public struct InstructionOffset { + + readonly Instruction instruction; + readonly int? offset; + + public int Offset { + get { + if (instruction != null) + return instruction.Offset; + if (offset.HasValue) + return offset.Value; + + throw new NotSupportedException (); + } + } + + public bool IsEndOfMethod { + get { return instruction == null && !offset.HasValue; } + } + + public InstructionOffset (Instruction instruction) + { + if (instruction == null) + throw new ArgumentNullException ("instruction"); + + this.instruction = instruction; + this.offset = null; + } + + public InstructionOffset (int offset) + { + this.instruction = null; + this.offset = offset; + } + } + + [Flags] + public enum VariableAttributes : ushort { + None = 0, + DebuggerHidden = 1, + } + + public struct VariableIndex { + readonly VariableDefinition variable; + readonly int? index; + + public int Index { + get { + if (variable != null) + return variable.Index; + if (index.HasValue) + return index.Value; + + throw new NotSupportedException (); + } + } + + public VariableIndex (VariableDefinition variable) + { + if (variable == null) + throw new ArgumentNullException ("variable"); + + this.variable = variable; + this.index = null; + } + + public VariableIndex (int index) + { + this.variable = null; + this.index = index; + } + } + + public abstract class DebugInformation : ICustomDebugInformationProvider { + + internal MetadataToken token; + internal Collection custom_infos; + + 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 () + { + } + } + + public sealed class VariableDebugInformation : DebugInformation { + + string name; + ushort attributes; + internal VariableIndex index; + + public int Index { + get { return index.Index; } + } + + public string Name { + get { return name; } + set { name = value; } + } + + public VariableAttributes Attributes { + get { return (VariableAttributes) attributes; } + set { attributes = (ushort) value; } + } + + public bool IsDebuggerHidden { + get { return attributes.GetAttributes ((ushort) VariableAttributes.DebuggerHidden); } + set { attributes = attributes.SetAttributes ((ushort) VariableAttributes.DebuggerHidden, value); } + } + + internal VariableDebugInformation (int index, string name) + { + if (name == null) + throw new ArgumentNullException ("name"); + + this.index = new VariableIndex (index); + this.name = name; + } + + public VariableDebugInformation (VariableDefinition variable, string name) + { + if (variable == null) + throw new ArgumentNullException ("variable"); + if (name == null) + throw new ArgumentNullException ("name"); + + this.index = new VariableIndex (variable); + this.name = name; + this.token = new MetadataToken (TokenType.LocalVariable); + } + } + + public sealed class ConstantDebugInformation : DebugInformation { + + string name; + TypeReference constant_type; + object value; + + public string Name { + get { return name; } + set { name = value; } + } + + public TypeReference ConstantType { + get { return constant_type; } + set { constant_type = value; } + } + + public object Value { + get { return value; } + set { this.value = value; } + } + + public ConstantDebugInformation (string name, TypeReference constant_type, object value) + { + if (name == null) + throw new ArgumentNullException ("name"); + + this.name = name; + this.constant_type = constant_type; + this.value = value; + this.token = new MetadataToken (TokenType.LocalConstant); + } + } + + public enum ImportTargetKind : byte { + ImportNamespace = 1, + ImportNamespaceInAssembly = 2, + ImportType = 3, + ImportXmlNamespaceWithAlias = 4, + ImportAlias = 5, + DefineAssemblyAlias = 6, + DefineNamespaceAlias = 7, + DefineNamespaceInAssemblyAlias = 8, + DefineTypeAlias = 9, + } + + public sealed class ImportTarget { + + internal ImportTargetKind kind; + + internal string @namespace; + internal TypeReference type; + internal AssemblyNameReference reference; + internal string alias; + + public string Namespace { + get { return @namespace; } + set { @namespace = value; } + } + + public TypeReference Type { + get { return type; } + set { type = value; } + } + + public AssemblyNameReference AssemblyReference { + get { return reference; } + set { reference = value; } + } + + public string Alias { + get { return alias; } + set { alias = value; } + } + + public ImportTargetKind Kind { + get { return kind; } + set { kind = value; } + } + + public ImportTarget (ImportTargetKind kind) + { + this.kind = kind; + } + } + + public sealed class ImportDebugInformation : DebugInformation { + + internal ImportDebugInformation parent; + internal Collection targets; + + public bool HasTargets { + get { return !targets.IsNullOrEmpty (); } + } + + public Collection Targets { + get { return targets ?? (targets = new Collection ()); } + } + + public ImportDebugInformation Parent { + get { return parent; } + set { parent = value; } + } + + public ImportDebugInformation () + { + this.token = new MetadataToken (TokenType.ImportScope); + } + } + + public interface ICustomDebugInformationProvider : IMetadataTokenProvider { + bool HasCustomDebugInformations { get; } + Collection CustomDebugInformations { get; } + } + + public enum CustomDebugInformationKind { + Binary, + StateMachineScope, + DynamicVariable, + DefaultNamespace, + AsyncMethodBody, + EmbeddedSource, + SourceLink, + } + + public abstract class CustomDebugInformation : DebugInformation { + + Guid identifier; + + public Guid Identifier { + get { return identifier; } + } + + public abstract CustomDebugInformationKind Kind { get; } + + internal CustomDebugInformation (Guid identifier) + { + this.identifier = identifier; + this.token = new MetadataToken (TokenType.CustomDebugInformation); + } + } + + public sealed class BinaryCustomDebugInformation : CustomDebugInformation { + + byte [] data; + + public byte [] Data { + get { return data; } + set { data = value; } + } + + public override CustomDebugInformationKind Kind { + get { return CustomDebugInformationKind.Binary; } + } + + public BinaryCustomDebugInformation (Guid identifier, byte [] data) + : base (identifier) + { + this.data = data; + } + } + + public sealed class AsyncMethodBodyDebugInformation : CustomDebugInformation { + + internal InstructionOffset catch_handler; + internal Collection 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 AsyncMethodBodyDebugInformation () + : base (KindIdentifier) + { + this.catch_handler = new InstructionOffset (-1); + } + } + + 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 = end != null ? new InstructionOffset (end) : new InstructionOffset (); + } + } + + public sealed class EmbeddedSourceDebugInformation : CustomDebugInformation { + + internal byte [] content; + internal bool compress; + + public byte [] Content { + get { return content; } + set { content = value; } + } + + public bool Compress { + get { return compress; } + set { compress = value; } + } + + public override CustomDebugInformationKind Kind { + get { return CustomDebugInformationKind.EmbeddedSource; } + } + + public static Guid KindIdentifier = new Guid ("{0E8A571B-6926-466E-B4AD-8AB04611F5FE}"); + + public EmbeddedSourceDebugInformation (byte [] content, bool compress) + : base (KindIdentifier) + { + this.content = content; + this.compress = compress; + } + } + + public sealed class SourceLinkDebugInformation : CustomDebugInformation { + + internal string content; + + public string Content { + get { return content; } + set { content = value; } + } + + public override CustomDebugInformationKind Kind { + get { return CustomDebugInformationKind.SourceLink; } + } + + public static Guid KindIdentifier = new Guid ("{CC110556-A091-4D38-9FEC-25AB9A351A6A}"); + + public SourceLinkDebugInformation (string content) + : base (KindIdentifier) + { + this.content = content; + } + } + + public sealed class MethodDebugInformation : DebugInformation { + + internal MethodDefinition method; + internal Collection 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 IDictionary GetSequencePointMapping () + { + var instruction_mapping = new Dictionary (); + if (!HasSequencePoints || !method.HasBody) + return instruction_mapping; + + var offset_mapping = new Dictionary (sequence_points.Count); + + for (int i = 0; i < sequence_points.Count; i++) { + if (!offset_mapping.ContainsKey (sequence_points [i].Offset)) + offset_mapping.Add (sequence_points [i].Offset, sequence_points [i]); + } + + var instructions = method.Body.Instructions; + + for (int i = 0; i < instructions.Count; i++) { + SequencePoint sequence_point; + if (offset_mapping.TryGetValue (instructions [i].Offset, out sequence_point)) + instruction_mapping.Add (instructions [i], sequence_point); + } + + return instruction_mapping; + } + + public IEnumerable 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 bool TryGetName (VariableDefinition variable, out string name) + { + name = null; + + var has_name = false; + var unique_name = ""; + + foreach (var scope in GetScopes ()) { + string slot_name; + if (!scope.TryGetName (variable, out slot_name)) + continue; + + if (!has_name) { + has_name = true; + unique_name = slot_name; + continue; + } + + if (unique_name != slot_name) + return false; + } + + name = unique_name; + return has_name; + } + } + + public interface ISymbolReader : IDisposable { +#if !READ_ONLY + ISymbolWriterProvider GetWriterProvider (); +#endif + bool ProcessDebugHeader (ImageDebugHeader header); + MethodDebugInformation Read (MethodDefinition method); + } + + public interface ISymbolReaderProvider { + ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName); + ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream); + } + + public class DefaultSymbolReaderProvider : ISymbolReaderProvider { + + readonly bool throw_if_no_symbol; + + public DefaultSymbolReaderProvider () + : this (throwIfNoSymbol: true) + { + } + + public DefaultSymbolReaderProvider (bool throwIfNoSymbol) + { + throw_if_no_symbol = throwIfNoSymbol; + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) + { + if (module.Image.HasDebugTables ()) + return null; + + if (module.HasDebugHeader) { + var header = module.GetDebugHeader (); + var entry = header.GetEmbeddedPortablePdbEntry (); + if (entry != null) + return new EmbeddedPortablePdbReaderProvider ().GetSymbolReader (module, fileName); + } + + var pdb_file_name = Mixin.GetPdbFileName (fileName); + + if (File.Exists (pdb_file_name)) { + if (Mixin.IsPortablePdb (Mixin.GetPdbFileName (fileName))) + return new PortablePdbReaderProvider ().GetSymbolReader (module, fileName); + + try { + return SymbolProvider.GetReaderProvider (SymbolKind.NativePdb).GetSymbolReader (module, fileName); + } catch (TypeLoadException) { + // We might not include support for native pdbs. + } + } + + var mdb_file_name = Mixin.GetMdbFileName (fileName); + if (File.Exists (mdb_file_name)) { + try { + return SymbolProvider.GetReaderProvider (SymbolKind.Mdb).GetSymbolReader (module, fileName); + } catch (TypeLoadException) { + // We might not include support for mdbs. + } + } + + if (throw_if_no_symbol) + throw new FileNotFoundException (string.Format ("No symbol found for file: {0}", fileName)); + + return null; + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + throw new NotSupportedException (); + } + } + + enum SymbolKind { + NativePdb, + PortablePdb, + EmbeddedPortablePdb, + Mdb, + } + + static class SymbolProvider { + + static SR.AssemblyName GetSymbolAssemblyName (SymbolKind kind) + { + if (kind == SymbolKind.PortablePdb) + throw new ArgumentException (); + + var suffix = GetSymbolNamespace (kind); + + var cecil_name = typeof (SymbolProvider).Assembly ().GetName (); + + var name = new SR.AssemblyName { + Name = cecil_name.Name + "." + suffix, + Version = cecil_name.Version, + }; + + name.SetPublicKeyToken (cecil_name.GetPublicKeyToken ()); + + return name; + } + + static Type GetSymbolType (SymbolKind kind, string fullname) + { + var type = Type.GetType (fullname); + if (type != null) + return type; + + var assembly_name = GetSymbolAssemblyName (kind); + + type = Type.GetType (fullname + ", " + assembly_name.FullName); + if (type != null) + return type; + + try { + var assembly = SR.Assembly.Load (assembly_name); + if (assembly != null) + return assembly.GetType (fullname); + } catch (FileNotFoundException) { + } catch (FileLoadException) { + } + + return null; + } + + public static ISymbolReaderProvider GetReaderProvider (SymbolKind kind) + { + if (kind == SymbolKind.PortablePdb) + return new PortablePdbReaderProvider (); + if (kind == SymbolKind.EmbeddedPortablePdb) + return new EmbeddedPortablePdbReaderProvider (); + + var provider_name = GetSymbolTypeName (kind, "ReaderProvider"); + var type = GetSymbolType (kind, provider_name); + if (type == null) + throw new TypeLoadException ("Could not find symbol provider type " + provider_name); + + return (ISymbolReaderProvider) Activator.CreateInstance (type); + } + + static string GetSymbolTypeName (SymbolKind kind, string name) + { + return "Mono.Cecil" + "." + GetSymbolNamespace (kind) + "." + kind + name; + } + + static string GetSymbolNamespace (SymbolKind kind) + { + if (kind == SymbolKind.PortablePdb || kind == SymbolKind.EmbeddedPortablePdb) + return "Cil"; + if (kind == SymbolKind.NativePdb) + return "Pdb"; + if (kind == SymbolKind.Mdb) + return "Mdb"; + + throw new ArgumentException (); + } + } + +#if !READ_ONLY + + public interface ISymbolWriter : IDisposable { + + ISymbolReaderProvider GetReaderProvider (); + ImageDebugHeader GetDebugHeader (); + void Write (MethodDebugInformation info); + } + + public interface ISymbolWriterProvider { + + ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName); + ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream); + } + + public class DefaultSymbolWriterProvider : ISymbolWriterProvider { + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + var reader = module.SymbolReader; + if (reader == null) + throw new InvalidOperationException (); + + if (module.Image != null && module.Image.HasDebugTables ()) + return null; + + return reader.GetWriterProvider ().GetSymbolWriter (module, fileName); + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + throw new NotSupportedException (); + } + } + +#endif +} + +namespace Mono.Cecil { + + static partial class Mixin { + + public static ImageDebugHeaderEntry GetCodeViewEntry (this ImageDebugHeader header) + { + return GetEntry (header, ImageDebugType.CodeView); + } + + public static ImageDebugHeaderEntry GetDeterministicEntry (this ImageDebugHeader header) + { + return GetEntry (header, ImageDebugType.Deterministic); + } + + public static ImageDebugHeader AddDeterministicEntry (this ImageDebugHeader header) + { + var entry = new ImageDebugHeaderEntry (new ImageDebugDirectory { Type = ImageDebugType.Deterministic }, Empty.Array); + if (header == null) + return new ImageDebugHeader (entry); + + var entries = new ImageDebugHeaderEntry [header.Entries.Length + 1]; + Array.Copy (header.Entries, entries, header.Entries.Length); + entries [entries.Length - 1] = entry; + return new ImageDebugHeader (entries); + } + + public static ImageDebugHeaderEntry GetEmbeddedPortablePdbEntry (this ImageDebugHeader header) + { + return GetEntry (header, ImageDebugType.EmbeddedPortablePdb); + } + + private static ImageDebugHeaderEntry GetEntry (this ImageDebugHeader header, ImageDebugType type) + { + if (!header.HasEntries) + return null; + + for (var i = 0; i < header.Entries.Length; i++) { + var entry = header.Entries [i]; + if (entry.Directory.Type == type) + return entry; + } + + return null; + } + + public static string GetPdbFileName (string assemblyFileName) + { + return Path.ChangeExtension (assemblyFileName, ".pdb"); + } + + public static string GetMdbFileName (string assemblyFileName) + { + return assemblyFileName + ".mdb"; + } + + public static bool IsPortablePdb (string fileName) + { + using (var file = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) + return IsPortablePdb (file); + } + + public static bool IsPortablePdb (Stream stream) + { + const uint ppdb_signature = 0x424a5342; + + if (stream.Length < 4) return false; + var position = stream.Position; + try { + var reader = new BinaryReader (stream); + return reader.ReadUInt32 () == ppdb_signature; + } finally { + stream.Position = position; + } + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.Cil/VariableDefinition.cs b/Mono.Cecil.20/Mono.Cecil.Cil/VariableDefinition.cs new file mode 100644 index 00000000..bd132846 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Cil/VariableDefinition.cs @@ -0,0 +1,29 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil.Cil { + + public sealed class VariableDefinition : VariableReference { + + public bool IsPinned { + get { return variable_type.IsPinned; } + } + + public VariableDefinition (TypeReference variableType) + : base (variableType) + { + } + + public override VariableDefinition Resolve () + { + return this; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.Cil/VariableReference.cs b/Mono.Cecil.20/Mono.Cecil.Cil/VariableReference.cs new file mode 100644 index 00000000..bc16bda0 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Cil/VariableReference.cs @@ -0,0 +1,49 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil.Cil { + + public abstract class VariableReference { + + internal int index = -1; + protected TypeReference variable_type; + + public TypeReference VariableType { + get { return variable_type; } + set { variable_type = value; } + } + + public int Index { + get { return index; } + } + + //兼容ILRT代码,不会被使用 + public string Name{ + get{ + return null; + } + } + + internal VariableReference (TypeReference variable_type) + { + this.variable_type = variable_type; + } + + public abstract VariableDefinition Resolve (); + + public override string ToString () + { + if (index >= 0) + return "V_" + index; + + return string.Empty; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.Metadata/BlobHeap.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/BlobHeap.cs new file mode 100644 index 00000000..574a130c --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/BlobHeap.cs @@ -0,0 +1,54 @@ +// +// 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; + +namespace Mono.Cecil.Metadata { + + sealed class BlobHeap : Heap { + + public BlobHeap (byte [] data) + : base (data) + { + } + + public byte [] Read (uint index) + { + if (index == 0 || index > this.data.Length - 1) + return Empty.Array; + + int position = (int) index; + int length = (int) data.ReadCompressedUInt32 (ref position); + + if (length > data.Length - position) + return Empty.Array; + + var buffer = new byte [length]; + + Buffer.BlockCopy (data, position, buffer, 0, length); + + return buffer; + } + + public void GetView (uint signature, out byte [] buffer, out int index, out int length) + { + if (signature == 0 || signature > data.Length - 1) { + buffer = null; + index = length = 0; + return; + } + + buffer = data; + + index = (int) signature; + length = (int) buffer.ReadCompressedUInt32 (ref index); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.Metadata/Buffers.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/Buffers.cs new file mode 100644 index 00000000..d87cb2a2 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/Buffers.cs @@ -0,0 +1,505 @@ +// +// 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.Text; + +using Mono.Cecil.PE; + +using RVA = System.UInt32; + +#if !READ_ONLY + +namespace Mono.Cecil.Metadata { + + sealed class TableHeapBuffer : HeapBuffer { + + readonly ModuleDefinition module; + readonly MetadataBuilder metadata; + + readonly internal TableInformation [] table_infos = new TableInformation [Mixin.TableCount]; + readonly internal MetadataTable [] tables = new MetadataTable [Mixin.TableCount]; + + bool large_string; + bool large_blob; + bool large_guid; + + readonly int [] coded_index_sizes = new int [Mixin.CodedIndexCount]; + readonly Func counter; + + internal uint [] string_offsets; + + public override bool IsEmpty { + get { return false; } + } + + public TableHeapBuffer (ModuleDefinition module, MetadataBuilder metadata) + : base (24) + { + this.module = module; + this.metadata = metadata; + this.counter = GetTableLength; + } + + int GetTableLength (Table table) + { + return (int) table_infos [(int) table].Length; + } + + public TTable GetTable (Table table) where TTable : MetadataTable, new () + { + var md_table = (TTable) tables [(int) table]; + if (md_table != null) + return md_table; + + md_table = new TTable (); + tables [(int) table] = md_table; + return md_table; + } + + public void WriteBySize (uint value, int size) + { + if (size == 4) + WriteUInt32 (value); + else + WriteUInt16 ((ushort) value); + } + + public void WriteBySize (uint value, bool large) + { + if (large) + WriteUInt32 (value); + else + WriteUInt16 ((ushort) value); + } + + public void WriteString (uint @string) + { + WriteBySize (string_offsets [@string], large_string); + } + + 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) + { + WriteBySize (rid, table_infos [(int) table].IsLarge); + } + + int GetCodedIndexSize (CodedIndex coded_index) + { + var index = (int) coded_index; + var size = coded_index_sizes [index]; + if (size != 0) + return size; + + return coded_index_sizes [index] = coded_index.GetSize (counter); + } + + public void WriteCodedRID (uint rid, CodedIndex coded_index) + { + WriteBySize (rid, GetCodedIndexSize (coded_index)); + } + + public void WriteTableHeap () + { + WriteUInt32 (0); // Reserved + WriteByte (GetTableHeapVersion ()); // MajorVersion + WriteByte (0); // MinorVersion + WriteByte (GetHeapSizes ()); // HeapSizes + WriteByte (10); // Reserved2 + WriteUInt64 (GetValid ()); // Valid + WriteUInt64 (0xc416003301fa00); // Sorted + + WriteRowCount (); + WriteTables (); + } + + void WriteRowCount () + { + for (int i = 0; i < tables.Length; i++) { + var table = tables [i]; + if (table == null || table.Length == 0) + continue; + + WriteUInt32 ((uint) table.Length); + } + } + + void WriteTables () + { + for (int i = 0; i < tables.Length; i++) { + var table = tables [i]; + if (table == null || table.Length == 0) + continue; + + table.Write (this); + } + } + + ulong GetValid () + { + ulong valid = 0; + + for (int i = 0; i < tables.Length; i++) { + var table = tables [i]; + if (table == null || table.Length == 0) + continue; + + table.Sort (); + valid |= (1UL << i); + } + + return valid; + } + + public void ComputeTableInformations () + { + if (metadata.metadata_builder != null) + ComputeTableInformations (metadata.metadata_builder.table_heap); + + ComputeTableInformations (metadata.table_heap); + } + + void ComputeTableInformations (TableHeapBuffer table_heap) + { + var tables = table_heap.tables; + for (int i = 0; i < tables.Length; i++) { + var table = tables [i]; + if (table != null && table.Length > 0) + table_infos [i].Length = (uint) table.Length; + } + } + + byte GetHeapSizes () + { + byte heap_sizes = 0; + + if (metadata.string_heap.IsLarge) { + large_string = true; + 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; + } + + return heap_sizes; + } + + byte GetTableHeapVersion () + { + switch (module.Runtime) { + case TargetRuntime.Net_1_0: + case TargetRuntime.Net_1_1: + return 1; + default: + return 2; + } + } + + public void FixupData (RVA data_rva) + { + var table = GetTable (Table.FieldRVA); + if (table.length == 0) + return; + + var field_idx_size = GetTable (Table.Field).IsLarge ? 4 : 2; + var previous = this.position; + + base.position = table.position; + for (int i = 0; i < table.length; i++) { + var rva = ReadUInt32 (); + base.position -= 4; + WriteUInt32 (rva + data_rva); + base.position += field_idx_size; + } + + base.position = previous; + } + } + + sealed class ResourceBuffer : ByteBuffer { + + public ResourceBuffer () + : base (0) + { + } + + public uint AddResource (byte [] resource) + { + var offset = (uint) this.position; + WriteInt32 (resource.Length); + WriteBytes (resource); + return offset; + } + } + + sealed class DataBuffer : ByteBuffer { + + public DataBuffer () + : base (0) + { + } + + public RVA AddData (byte [] data) + { + var rva = (RVA) position; + WriteBytes (data); + return rva; + } + } + + abstract class HeapBuffer : ByteBuffer { + + public bool IsLarge { + get { return base.length > 65535; } + } + + public abstract bool IsEmpty { get; } + + protected HeapBuffer (int length) + : base (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 { + + protected Dictionary strings = new Dictionary (StringComparer.Ordinal); + + public sealed override bool IsEmpty { + get { return length <= 1; } + } + + public StringHeapBuffer () + : base (1) + { + WriteByte (0); + } + + public virtual uint GetStringIndex (string @string) + { + uint index; + if (strings.TryGetValue (@string, out index)) + return index; + + index = (uint) strings.Count + 1; + strings.Add (@string, index); + return index; + } + + public uint [] WriteStrings () + { + var sorted = SortStrings (strings); + strings = null; + + // Add 1 for empty string whose index and offset are both 0 + var string_offsets = new uint [sorted.Count + 1]; + string_offsets [0] = 0; + + // Find strings that can be folded + var previous = string.Empty; + foreach (var entry in sorted) { + var @string = entry.Key; + var index = entry.Value; + var position = base.position; + + if (previous.EndsWith (@string, StringComparison.Ordinal) && !IsLowSurrogateChar (entry.Key [0])) { + // Map over the tail of prev string. Watch for null-terminator of prev string. + string_offsets [index] = (uint) (position - (Encoding.UTF8.GetByteCount (entry.Key) + 1)); + } else { + string_offsets [index] = (uint) position; + WriteString (@string); + } + + previous = entry.Key; + } + + return string_offsets; + } + + static List> SortStrings (Dictionary strings) + { + var sorted = new List> (strings); + sorted.Sort (new SuffixSort ()); + return sorted; + } + + static bool IsLowSurrogateChar (int c) + { + return unchecked((uint)(c - 0xDC00)) <= 0xDFFF - 0xDC00; + } + + protected virtual void WriteString (string @string) + { + WriteBytes (Encoding.UTF8.GetBytes (@string)); + WriteByte (0); + } + + // Sorts strings such that a string is followed immediately by all strings + // that are a suffix of it. + private class SuffixSort : IComparer> { + + public int Compare(KeyValuePair xPair, KeyValuePair yPair) + { + var x = xPair.Key; + var y = yPair.Key; + + for (int i = x.Length - 1, j = y.Length - 1; i >= 0 & j >= 0; i--, j--) { + if (x [i] < y [j]) { + return -1; + } + + if (x [i] > y [j]) { + return +1; + } + } + + return y.Length.CompareTo (x.Length); + } + } + } + + sealed class BlobHeapBuffer : HeapBuffer { + + readonly Dictionary blobs = new Dictionary (new ByteBufferEqualityComparer ()); + + public override bool IsEmpty { + get { return length <= 1; } + } + + public BlobHeapBuffer () + : base (1) + { + WriteByte (0); + } + + public uint GetBlobIndex (ByteBuffer blob) + { + uint index; + if (blobs.TryGetValue (blob, out index)) + return index; + + index = (uint) base.position; + WriteBlob (blob); + blobs.Add (blob, index); + return index; + } + + void WriteBlob (ByteBuffer blob) + { + WriteCompressedUInt32 ((uint) blob.length); + WriteBytes (blob); + } + } + + sealed class UserStringHeapBuffer : StringHeapBuffer { + + public override uint GetStringIndex (string @string) + { + uint index; + if (strings.TryGetValue (@string, out index)) + return index; + + index = (uint) base.position; + WriteString (@string); + strings.Add (@string, index); + return index; + } + + protected override void WriteString (string @string) + { + WriteCompressedUInt32 ((uint) @string.Length * 2 + 1); + + byte special = 0; + + for (int i = 0; i < @string.Length; i++) { + var @char = @string [i]; + WriteUInt16 (@char); + + if (special == 1) + continue; + + if (@char < 0x20 || @char > 0x7e) { + if (@char > 0x7e + || (@char >= 0x01 && @char <= 0x08) + || (@char >= 0x0e && @char <= 0x1f) + || @char == 0x27 + || @char == 0x2d) { + + special = 1; + } + } + } + + WriteByte (special); + } + } + + sealed class PdbHeapBuffer : HeapBuffer { + + public override bool IsEmpty { + get { return false; } + } + + public PdbHeapBuffer () + : base (0) + { + } + } +} + +#endif diff --git a/Mono.Cecil.20/Mono.Cecil.Metadata/CodedIndex.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/CodedIndex.cs new file mode 100644 index 00000000..2026a8a7 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/CodedIndex.cs @@ -0,0 +1,29 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil.Metadata { + + enum CodedIndex { + TypeDefOrRef, + HasConstant, + HasCustomAttribute, + HasFieldMarshal, + HasDeclSecurity, + MemberRefParent, + HasSemantics, + MethodDefOrRef, + MemberForwarded, + Implementation, + CustomAttributeType, + ResolutionScope, + TypeOrMethodDef, + HasCustomDebugInformation, + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/ElementType.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/ElementType.cs similarity index 57% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/ElementType.cs rename to Mono.Cecil.20/Mono.Cecil.Metadata/ElementType.cs index 72fc1cca..2190160a 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/ElementType.cs +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/ElementType.cs @@ -1,29 +1,11 @@ // -// ElementType.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // namespace Mono.Cecil.Metadata { diff --git a/Mono.Cecil.20/Mono.Cecil.Metadata/GuidHeap.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/GuidHeap.cs new file mode 100644 index 00000000..76ec9d1d --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/GuidHeap.cs @@ -0,0 +1,36 @@ +// +// 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; + +namespace Mono.Cecil.Metadata { + + sealed class GuidHeap : Heap { + + public GuidHeap (byte [] data) + : base (data) + { + } + + public Guid Read (uint index) + { + const int guid_size = 16; + + if (index == 0 || ((index - 1) + guid_size) > data.Length) + return new Guid (); + + var buffer = new byte [guid_size]; + + Buffer.BlockCopy (this.data, (int) ((index - 1) * guid_size), buffer, 0, guid_size); + + return new Guid (buffer); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.Metadata/Heap.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/Heap.cs new file mode 100644 index 00000000..6874d796 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/Heap.cs @@ -0,0 +1,24 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil.Metadata { + + abstract class Heap { + + public int IndexSize; + + readonly internal byte [] data; + + protected Heap (byte [] data) + { + this.data = data; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/MetadataToken.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/MetadataToken.cs similarity index 54% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/MetadataToken.cs rename to Mono.Cecil.20/Mono.Cecil.Metadata/MetadataToken.cs index bda56b0f..a8b712e7 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/MetadataToken.cs +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/MetadataToken.cs @@ -1,34 +1,18 @@ // -// MetadataToken.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // +using System; + namespace Mono.Cecil { - public struct MetadataToken { + public struct MetadataToken : IEquatable { readonly uint token; @@ -77,6 +61,11 @@ public override int GetHashCode () return (int) token; } + public bool Equals (MetadataToken other) + { + return other.token == token; + } + public override bool Equals (object obj) { if (obj is MetadataToken) { diff --git a/Mono.Cecil.20/Mono.Cecil.Metadata/PdbHeap.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/PdbHeap.cs new file mode 100644 index 00000000..39e275ad --- /dev/null +++ b/Mono.Cecil.20/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 (byte [] data) + : base (data) + { + } + + public bool HasTable (Table table) + { + return (TypeSystemTables & (1L << (int) table)) != 0; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Row.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/Row.cs similarity index 65% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Row.cs rename to Mono.Cecil.20/Mono.Cecil.Metadata/Row.cs index 9975b7ba..0c05ebad 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Row.cs +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/Row.cs @@ -1,36 +1,18 @@ // -// Row.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System.Collections.Generic; namespace Mono.Cecil.Metadata { - class Row { + struct Row { internal T1 Col1; internal T2 Col2; @@ -41,8 +23,7 @@ public Row (T1 col1, T2 col2) } } - class Row - { + struct Row { internal T1 Col1; internal T2 Col2; internal T3 Col3; @@ -55,8 +36,7 @@ public Row (T1 col1, T2 col2, T3 col3) } } - class Row - { + struct Row { internal T1 Col1; internal T2 Col2; internal T3 Col3; @@ -71,8 +51,7 @@ public Row (T1 col1, T2 col2, T3 col3, T4 col4) } } - class Row - { + struct Row { internal T1 Col1; internal T2 Col2; internal T3 Col3; @@ -89,8 +68,7 @@ public Row (T1 col1, T2 col2, T3 col3, T4 col4, T5 col5) } } - class Row - { + struct Row { internal T1 Col1; internal T2 Col2; internal T3 Col3; @@ -109,8 +87,7 @@ public Row (T1 col1, T2 col2, T3 col3, T4 col4, T5 col5, T6 col6) } } - class Row - { + struct Row { internal T1 Col1; internal T2 Col2; internal T3 Col3; diff --git a/Mono.Cecil.20/Mono.Cecil.Metadata/StringHeap.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/StringHeap.cs new file mode 100644 index 00000000..4bde70e2 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/StringHeap.cs @@ -0,0 +1,60 @@ +// +// 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.Text; + +namespace Mono.Cecil.Metadata { + + class StringHeap : Heap { + + readonly Dictionary strings = new Dictionary (); + + public StringHeap (byte [] data) + : base (data) + { + } + + public string Read (uint index) + { + if (index == 0) + return string.Empty; + + string @string; + if (strings.TryGetValue (index, out @string)) + return @string; + + if (index > data.Length - 1) + return string.Empty; + + @string = ReadStringAt (index); + if (@string.Length != 0) + strings.Add (index, @string); + + return @string; + } + + protected virtual string ReadStringAt (uint index) + { + int length = 0; + int start = (int) index; + + for (int i = start; ; i++) { + if (data [i] == 0) + break; + + length++; + } + + return Encoding.UTF8.GetString (data, start, length); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TableHeap.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/TableHeap.cs similarity index 54% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TableHeap.cs rename to Mono.Cecil.20/Mono.Cecil.Metadata/TableHeap.cs index 9bc0edd3..dee655a3 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TableHeap.cs +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/TableHeap.cs @@ -1,29 +1,11 @@ // -// TableHeap.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; @@ -77,12 +59,25 @@ 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 { public uint Offset; public uint Length; public uint RowSize; + + public bool IsLarge { + get { return Length > ushort.MaxValue; } + } } sealed class TableHeap : Heap { @@ -90,16 +85,14 @@ 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]; } } - public TableHeap (Section section, uint start, uint size) - : base (section, start, size) + public TableHeap (byte [] data) + : base (data) { } diff --git a/Mono.Cecil.20/Mono.Cecil.Metadata/TokenType.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/TokenType.cs new file mode 100644 index 00000000..547f6c64 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/TokenType.cs @@ -0,0 +1,49 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum TokenType : uint { + Module = 0x00000000, + TypeRef = 0x01000000, + TypeDef = 0x02000000, + Field = 0x04000000, + Method = 0x06000000, + Param = 0x08000000, + InterfaceImpl = 0x09000000, + MemberRef = 0x0a000000, + CustomAttribute = 0x0c000000, + Permission = 0x0e000000, + Signature = 0x11000000, + Event = 0x14000000, + Property = 0x17000000, + ModuleRef = 0x1a000000, + TypeSpec = 0x1b000000, + Assembly = 0x20000000, + AssemblyRef = 0x23000000, + File = 0x26000000, + ExportedType = 0x27000000, + ManifestResource = 0x28000000, + 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.20/Mono.Cecil.Metadata/UserStringHeap.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/UserStringHeap.cs new file mode 100644 index 00000000..7b1b42ff --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/UserStringHeap.cs @@ -0,0 +1,36 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil.Metadata { + + sealed class UserStringHeap : StringHeap { + + public UserStringHeap (byte [] data) + : base (data) + { + } + + protected override string ReadStringAt (uint index) + { + int start = (int) index; + + uint length = (uint) (data.ReadCompressedUInt32 (ref start) & ~1); + if (length < 1) + return string.Empty; + + var chars = new char [length / 2]; + + for (int i = start, j = 0; i < start + length; i += 2) + chars [j++] = (char) (data [i] | (data [i + 1] << 8)); + + return new string (chars); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.Metadata/Utilities.cs b/Mono.Cecil.20/Mono.Cecil.Metadata/Utilities.cs new file mode 100644 index 00000000..3a4330da --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.Metadata/Utilities.cs @@ -0,0 +1,652 @@ +// +// 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 Mono.Cecil.Metadata; + +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; + if ((data [position] & 0x80) == 0) { + integer = data [position]; + position++; + } else if ((data [position] & 0x40) == 0) { + integer = (uint) (data [position] & ~0x80) << 8; + integer |= data [position + 1]; + position += 2; + } else { + integer = (uint) (data [position] & ~0xc0) << 24; + integer |= (uint) data [position + 1] << 16; + integer |= (uint) data [position + 2] << 8; + integer |= (uint) data [position + 3]; + position += 4; + } + return integer; + } + + public static MetadataToken GetMetadataToken (this CodedIndex self, uint data) + { + uint rid; + TokenType token_type; + switch (self) { + case CodedIndex.TypeDefOrRef: + rid = data >> 2; + switch (data & 3) { + case 0: + token_type = TokenType.TypeDef; goto ret; + case 1: + token_type = TokenType.TypeRef; goto ret; + case 2: + token_type = TokenType.TypeSpec; goto ret; + default: + goto exit; + } + case CodedIndex.HasConstant: + rid = data >> 2; + switch (data & 3) { + case 0: + token_type = TokenType.Field; goto ret; + case 1: + token_type = TokenType.Param; goto ret; + case 2: + token_type = TokenType.Property; goto ret; + default: + goto exit; + } + case CodedIndex.HasCustomAttribute: + 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; + default: + goto exit; + } + case CodedIndex.HasFieldMarshal: + rid = data >> 1; + switch (data & 1) { + case 0: + token_type = TokenType.Field; goto ret; + case 1: + token_type = TokenType.Param; goto ret; + default: + goto exit; + } + case CodedIndex.HasDeclSecurity: + rid = data >> 2; + switch (data & 3) { + case 0: + token_type = TokenType.TypeDef; goto ret; + case 1: + token_type = TokenType.Method; goto ret; + case 2: + token_type = TokenType.Assembly; goto ret; + default: + goto exit; + } + case CodedIndex.MemberRefParent: + rid = data >> 3; + switch (data & 7) { + case 0: + token_type = TokenType.TypeDef; goto ret; + case 1: + token_type = TokenType.TypeRef; goto ret; + case 2: + token_type = TokenType.ModuleRef; goto ret; + case 3: + token_type = TokenType.Method; goto ret; + case 4: + token_type = TokenType.TypeSpec; goto ret; + default: + goto exit; + } + case CodedIndex.HasSemantics: + rid = data >> 1; + switch (data & 1) { + case 0: + token_type = TokenType.Event; goto ret; + case 1: + token_type = TokenType.Property; goto ret; + default: + goto exit; + } + case CodedIndex.MethodDefOrRef: + rid = data >> 1; + switch (data & 1) { + case 0: + token_type = TokenType.Method; goto ret; + case 1: + token_type = TokenType.MemberRef; goto ret; + default: + goto exit; + } + case CodedIndex.MemberForwarded: + rid = data >> 1; + switch (data & 1) { + case 0: + token_type = TokenType.Field; goto ret; + case 1: + token_type = TokenType.Method; goto ret; + default: + goto exit; + } + case CodedIndex.Implementation: + rid = data >> 2; + switch (data & 3) { + case 0: + token_type = TokenType.File; goto ret; + case 1: + token_type = TokenType.AssemblyRef; goto ret; + case 2: + token_type = TokenType.ExportedType; goto ret; + default: + goto exit; + } + case CodedIndex.CustomAttributeType: + rid = data >> 3; + switch (data & 7) { + case 2: + token_type = TokenType.Method; goto ret; + case 3: + token_type = TokenType.MemberRef; goto ret; + default: + goto exit; + } + case CodedIndex.ResolutionScope: + rid = data >> 2; + switch (data & 3) { + case 0: + token_type = TokenType.Module; goto ret; + case 1: + token_type = TokenType.ModuleRef; goto ret; + case 2: + token_type = TokenType.AssemblyRef; goto ret; + case 3: + token_type = TokenType.TypeRef; goto ret; + default: + goto exit; + } + case CodedIndex.TypeOrMethodDef: + rid = data >> 1; + switch (data & 1) { + case 0: + token_type = TokenType.TypeDef; goto ret; + case 1: + 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; + } + ret: + return new MetadataToken (token_type, rid); + exit: + return MetadataToken.Zero; + } + +#if !READ_ONLY + public static uint CompressMetadataToken (this CodedIndex self, MetadataToken token) + { + uint ret = 0; + if (token.RID == 0) + return ret; + switch (self) { + case CodedIndex.TypeDefOrRef: + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.TypeDef: + return ret | 0; + case TokenType.TypeRef: + return ret | 1; + case TokenType.TypeSpec: + return ret | 2; + default: + goto exit; + } + case CodedIndex.HasConstant: + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.Field: + return ret | 0; + case TokenType.Param: + return ret | 1; + case TokenType.Property: + return ret | 2; + default: + goto exit; + } + case CodedIndex.HasCustomAttribute: + 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; + default: + goto exit; + } + case CodedIndex.HasFieldMarshal: + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Field: + return ret | 0; + case TokenType.Param: + return ret | 1; + default: + goto exit; + } + case CodedIndex.HasDeclSecurity: + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.TypeDef: + return ret | 0; + case TokenType.Method: + return ret | 1; + case TokenType.Assembly: + return ret | 2; + default: + goto exit; + } + case CodedIndex.MemberRefParent: + ret = token.RID << 3; + switch (token.TokenType) { + case TokenType.TypeDef: + return ret | 0; + case TokenType.TypeRef: + return ret | 1; + case TokenType.ModuleRef: + return ret | 2; + case TokenType.Method: + return ret | 3; + case TokenType.TypeSpec: + return ret | 4; + default: + goto exit; + } + case CodedIndex.HasSemantics: + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Event: + return ret | 0; + case TokenType.Property: + return ret | 1; + default: + goto exit; + } + case CodedIndex.MethodDefOrRef: + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Method: + return ret | 0; + case TokenType.MemberRef: + return ret | 1; + default: + goto exit; + } + case CodedIndex.MemberForwarded: + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Field: + return ret | 0; + case TokenType.Method: + return ret | 1; + default: + goto exit; + } + case CodedIndex.Implementation: + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.File: + return ret | 0; + case TokenType.AssemblyRef: + return ret | 1; + case TokenType.ExportedType: + return ret | 2; + default: + goto exit; + } + case CodedIndex.CustomAttributeType: + ret = token.RID << 3; + switch (token.TokenType) { + case TokenType.Method: + return ret | 2; + case TokenType.MemberRef: + return ret | 3; + default: + goto exit; + } + case CodedIndex.ResolutionScope: + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.Module: + return ret | 0; + case TokenType.ModuleRef: + return ret | 1; + case TokenType.AssemblyRef: + return ret | 2; + case TokenType.TypeRef: + return ret | 3; + default: + goto exit; + } + case CodedIndex.TypeOrMethodDef: + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.TypeDef: + return ret | 0; + case TokenType.Method: + return ret | 1; + 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; + } + exit: + throw new ArgumentException (); + } +#endif + + public static int GetSize (this CodedIndex self, Func counter) + { + int bits; + Table [] tables; + + switch (self) { + case CodedIndex.TypeDefOrRef: + bits = 2; + tables = new [] { Table.TypeDef, Table.TypeRef, Table.TypeSpec }; + break; + case CodedIndex.HasConstant: + bits = 2; + tables = new [] { Table.Field, Table.Param, Table.Property }; + break; + case CodedIndex.HasCustomAttribute: + 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, + }; + break; + case CodedIndex.HasFieldMarshal: + bits = 1; + tables = new [] { Table.Field, Table.Param }; + break; + case CodedIndex.HasDeclSecurity: + bits = 2; + tables = new [] { Table.TypeDef, Table.Method, Table.Assembly }; + break; + case CodedIndex.MemberRefParent: + bits = 3; + tables = new [] { Table.TypeDef, Table.TypeRef, Table.ModuleRef, Table.Method, Table.TypeSpec }; + break; + case CodedIndex.HasSemantics: + bits = 1; + tables = new [] { Table.Event, Table.Property }; + break; + case CodedIndex.MethodDefOrRef: + bits = 1; + tables = new [] { Table.Method, Table.MemberRef }; + break; + case CodedIndex.MemberForwarded: + bits = 1; + tables = new [] { Table.Field, Table.Method }; + break; + case CodedIndex.Implementation: + bits = 2; + tables = new [] { Table.File, Table.AssemblyRef, Table.ExportedType }; + break; + case CodedIndex.CustomAttributeType: + bits = 3; + tables = new [] { Table.Method, Table.MemberRef }; + break; + case CodedIndex.ResolutionScope: + bits = 2; + tables = new [] { Table.Module, Table.ModuleRef, Table.AssemblyRef, Table.TypeRef }; + break; + case CodedIndex.TypeOrMethodDef: + 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 (); + } + + int max = 0; + + for (int i = 0; i < tables.Length; i++) { + max = System.Math.Max (counter (tables [i]), max); + } + + return max < (1 << (16 - bits)) ? 2 : 4; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.PE/BinaryStreamReader.cs b/Mono.Cecil.20/Mono.Cecil.PE/BinaryStreamReader.cs new file mode 100644 index 00000000..812adbc5 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.PE/BinaryStreamReader.cs @@ -0,0 +1,54 @@ +// +// 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.IO; + +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) + { + } + + public void Advance (int bytes) + { + BaseStream.Seek (bytes, SeekOrigin.Current); + } + + public void MoveTo (uint position) + { + BaseStream.Seek (position, SeekOrigin.Begin); + } + + public void Align (int align) + { + align--; + var position = Position; + Advance (((position + align) & ~align) - position); + } + + public DataDirectory ReadDataDirectory () + { + return new DataDirectory (ReadUInt32 (), ReadUInt32 ()); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.PE/BinaryStreamWriter.cs b/Mono.Cecil.20/Mono.Cecil.PE/BinaryStreamWriter.cs new file mode 100644 index 00000000..b741f684 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.PE/BinaryStreamWriter.cs @@ -0,0 +1,93 @@ +// +// 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.IO; + +#if !READ_ONLY + +namespace Mono.Cecil.PE { + + class BinaryStreamWriter : BinaryWriter { + + public int Position { + get { return (int) BaseStream.Position; } + set { BaseStream.Position = value; } + } + + public BinaryStreamWriter (Stream stream) + : base (stream) + { + } + + public void WriteByte (byte value) + { + Write (value); + } + + public void WriteUInt16 (ushort value) + { + Write (value); + } + + public void WriteInt16 (short value) + { + Write (value); + } + + public void WriteUInt32 (uint value) + { + Write (value); + } + + public void WriteInt32 (int value) + { + Write (value); + } + + public void WriteUInt64 (ulong value) + { + Write (value); + } + + public void WriteBytes (byte [] bytes) + { + Write (bytes); + } + + public void WriteDataDirectory (DataDirectory directory) + { + Write (directory.VirtualAddress); + Write (directory.Size); + } + + public void WriteBuffer (ByteBuffer buffer) + { + Write (buffer.buffer, 0, buffer.length); + } + + protected void Advance (int bytes) + { + BaseStream.Seek (bytes, SeekOrigin.Current); + } + + public void Align (int align) + { + align--; + var position = Position; + var bytes = ((position + align) & ~align) - position; + + for (int i = 0; i < bytes; i++) + WriteByte (0); + } + } +} + +#endif diff --git a/Mono.Cecil.20/Mono.Cecil.PE/ByteBuffer.cs b/Mono.Cecil.20/Mono.Cecil.PE/ByteBuffer.cs new file mode 100644 index 00000000..8aee04ba --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.PE/ByteBuffer.cs @@ -0,0 +1,341 @@ +// +// 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; + +namespace Mono.Cecil.PE { + + class ByteBuffer { + + internal byte [] buffer; + internal int length; + internal int position; + + public ByteBuffer () + { + this.buffer = Empty.Array; + } + + public ByteBuffer (int length) + { + this.buffer = new byte [length]; + } + + public ByteBuffer (byte [] buffer) + { + this.buffer = buffer ?? Empty.Array; + this.length = this.buffer.Length; + } + + public void Advance (int length) + { + position += length; + } + + public byte ReadByte () + { + return buffer [position++]; + } + + public sbyte ReadSByte () + { + return (sbyte) ReadByte (); + } + + public byte [] ReadBytes (int length) + { + var bytes = new byte [length]; + Buffer.BlockCopy (buffer, position, bytes, 0, length); + position += length; + return bytes; + } + + public ushort ReadUInt16 () + { + ushort value = (ushort) (buffer [position] + | (buffer [position + 1] << 8)); + position += 2; + return value; + } + + public short ReadInt16 () + { + return (short) ReadUInt16 (); + } + + public uint ReadUInt32 () + { + uint value = (uint) (buffer [position] + | (buffer [position + 1] << 8) + | (buffer [position + 2] << 16) + | (buffer [position + 3] << 24)); + position += 4; + return value; + } + + public int ReadInt32 () + { + return (int) ReadUInt32 (); + } + + public ulong ReadUInt64 () + { + uint low = ReadUInt32 (); + uint high = ReadUInt32 (); + + return (((ulong) high) << 32) | low; + } + + public long ReadInt64 () + { + return (long) ReadUInt64 (); + } + + public uint ReadCompressedUInt32 () + { + byte first = ReadByte (); + if ((first & 0x80) == 0) + return first; + + if ((first & 0x40) == 0) + return ((uint) (first & ~0x80) << 8) + | ReadByte (); + + return ((uint) (first & ~0xc0) << 24) + | (uint) ReadByte () << 16 + | (uint) ReadByte () << 8 + | ReadByte (); + } + + public int ReadCompressedInt32 () + { + 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 () + { + if (!BitConverter.IsLittleEndian) { + var bytes = ReadBytes (4); + Array.Reverse (bytes); + return BitConverter.ToSingle (bytes, 0); + } + + float value = BitConverter.ToSingle (buffer, position); + position += 4; + return value; + } + + public double ReadDouble () + { + if (!BitConverter.IsLittleEndian) { + var bytes = ReadBytes (8); + Array.Reverse (bytes); + return BitConverter.ToDouble (bytes, 0); + } + + double value = BitConverter.ToDouble (buffer, position); + position += 8; + return value; + } + +#if !READ_ONLY + + public void WriteByte (byte value) + { + if (position == buffer.Length) + Grow (1); + + buffer [position++] = value; + + if (position > length) + length = position; + } + + public void WriteSByte (sbyte value) + { + WriteByte ((byte) value); + } + + public void WriteUInt16 (ushort value) + { + if (position + 2 > buffer.Length) + Grow (2); + + buffer [position++] = (byte) value; + buffer [position++] = (byte) (value >> 8); + + if (position > length) + length = position; + } + + public void WriteInt16 (short value) + { + WriteUInt16 ((ushort) value); + } + + public void WriteUInt32 (uint value) + { + if (position + 4 > buffer.Length) + Grow (4); + + buffer [position++] = (byte) value; + buffer [position++] = (byte) (value >> 8); + buffer [position++] = (byte) (value >> 16); + buffer [position++] = (byte) (value >> 24); + + if (position > length) + length = position; + } + + public void WriteInt32 (int value) + { + WriteUInt32 ((uint) value); + } + + public void WriteUInt64 (ulong value) + { + if (position + 8 > buffer.Length) + Grow (8); + + buffer [position++] = (byte) value; + buffer [position++] = (byte) (value >> 8); + buffer [position++] = (byte) (value >> 16); + buffer [position++] = (byte) (value >> 24); + buffer [position++] = (byte) (value >> 32); + buffer [position++] = (byte) (value >> 40); + buffer [position++] = (byte) (value >> 48); + buffer [position++] = (byte) (value >> 56); + + if (position > length) + length = position; + } + + public void WriteInt64 (long value) + { + WriteUInt64 ((ulong) value); + } + + public void WriteCompressedUInt32 (uint value) + { + if (value < 0x80) + WriteByte ((byte) value); + else if (value < 0x4000) { + WriteByte ((byte) (0x80 | (value >> 8))); + WriteByte ((byte) (value & 0xff)); + } else { + WriteByte ((byte) ((value >> 24) | 0xc0)); + WriteByte ((byte) ((value >> 16) & 0xff)); + WriteByte ((byte) ((value >> 8) & 0xff)); + WriteByte ((byte) (value & 0xff)); + } + } + + public void WriteCompressedInt32 (int value) + { + if (value >= 0) { + WriteCompressedUInt32 ((uint) (value << 1)); + return; + } + + if (value > -0x40) + value = 0x40 + value; + else if (value >= -0x2000) + value = 0x2000 + value; + else if (value >= -0x20000000) + value = 0x20000000 + value; + + WriteCompressedUInt32 ((uint) ((value << 1) | 1)); + } + + public void WriteBytes (byte [] bytes) + { + var length = bytes.Length; + if (position + length > buffer.Length) + Grow (length); + + Buffer.BlockCopy (bytes, 0, buffer, position, length); + position += length; + + if (position > this.length) + this.length = position; + } + + public void WriteBytes (int length) + { + if (position + length > buffer.Length) + Grow (length); + + position += length; + + if (position > this.length) + this.length = position; + } + + public void WriteBytes (ByteBuffer buffer) + { + if (position + buffer.length > this.buffer.Length) + Grow (buffer.length); + + Buffer.BlockCopy (buffer.buffer, 0, this.buffer, position, buffer.length); + position += buffer.length; + + if (position > this.length) + this.length = position; + } + + public void WriteSingle (float value) + { + var bytes = BitConverter.GetBytes (value); + + if (!BitConverter.IsLittleEndian) + Array.Reverse (bytes); + + WriteBytes (bytes); + } + + public void WriteDouble (double value) + { + var bytes = BitConverter.GetBytes (value); + + if (!BitConverter.IsLittleEndian) + Array.Reverse (bytes); + + WriteBytes (bytes); + } + + void Grow (int desired) + { + var current = this.buffer; + var current_length = current.Length; + + var buffer = new byte [System.Math.Max (current_length + desired, current_length * 2)]; + Buffer.BlockCopy (current, 0, buffer, 0, current_length); + this.buffer = buffer; + } + +#endif + + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.PE/ByteBufferEqualityComparer.cs b/Mono.Cecil.20/Mono.Cecil.PE/ByteBufferEqualityComparer.cs new file mode 100644 index 00000000..8b7cb238 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.PE/ByteBufferEqualityComparer.cs @@ -0,0 +1,48 @@ +// +// 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; + +namespace Mono.Cecil.PE { + + sealed class ByteBufferEqualityComparer : IEqualityComparer { + + public bool Equals (ByteBuffer x, ByteBuffer y) + { + if (x.length != y.length) + return false; + + var x_buffer = x.buffer; + var y_buffer = y.buffer; + + for (int i = 0; i < x.length; i++) + if (x_buffer [i] != y_buffer [i]) + return false; + + return true; + } + + public int GetHashCode (ByteBuffer buffer) + { + // See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function + const int fnv_offset_bias = unchecked((int)2166136261); + const int fnv_prime = 16777619; + + var hash_code = fnv_offset_bias; + var bytes = buffer.buffer; + + for (int i = 0; i < buffer.length; i++) + hash_code = unchecked ((hash_code ^ bytes [i]) * fnv_prime); + + return hash_code; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.PE/DataDirectory.cs b/Mono.Cecil.20/Mono.Cecil.PE/DataDirectory.cs new file mode 100644 index 00000000..4922dd2f --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.PE/DataDirectory.cs @@ -0,0 +1,32 @@ +// +// 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 RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + struct DataDirectory { + + public readonly RVA VirtualAddress; + public readonly uint Size; + + public bool IsZero { + get { return VirtualAddress == 0 && Size == 0; } + } + + public DataDirectory (RVA rva, uint size) + { + this.VirtualAddress = rva; + this.Size = size; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.PE/Image.cs b/Mono.Cecil.20/Mono.Cecil.PE/Image.cs new file mode 100644 index 00000000..8160f94b --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.PE/Image.cs @@ -0,0 +1,166 @@ +// +// 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.IO; + +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Collections.Generic; + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + sealed class Image : IDisposable { + + public Disposable Stream; + public string FileName; + + public ModuleKind Kind; + public string RuntimeVersion; + public TargetArchitecture Architecture; + public ModuleCharacteristics Characteristics; + + public ImageDebugHeader DebugHeader; + + public Section [] Sections; + + public Section MetadataSection; + + public uint EntryPointToken; + public uint Timestamp; + public ModuleAttributes Attributes; + + public DataDirectory Debug; + public DataDirectory Resources; + public DataDirectory StrongName; + + public StringHeap StringHeap; + public BlobHeap BlobHeap; + public UserStringHeap UserStringHeap; + public GuidHeap GuidHeap; + public TableHeap TableHeap; + public PdbHeap PdbHeap; + + readonly int [] coded_index_sizes = new int [14]; + + readonly Func counter; + + public Image () + { + counter = GetTableLength; + } + + public bool HasTable (Table table) + { + return GetTableLength (table) > 0; + } + + public int GetTableLength (Table table) + { + return (int) TableHeap [table].Length; + } + + public int GetTableIndexSize (Table table) + { + return GetTableLength (table) < 65536 ? 2 : 4; + } + + public int GetCodedIndexSize (CodedIndex coded_index) + { + var index = (int) coded_index; + var size = coded_index_sizes [index]; + if (size != 0) + return size; + + return coded_index_sizes [index] = coded_index.GetSize (counter); + } + + public uint ResolveVirtualAddress (RVA rva) + { + var section = GetSectionAtVirtualAddress (rva); + if (section == null) + throw new ArgumentOutOfRangeException (); + + return ResolveVirtualAddressInSection (rva, section); + } + + public uint ResolveVirtualAddressInSection (RVA rva, Section section) + { + return rva + section.PointerToRawData - section.VirtualAddress; + } + + public Section GetSection (string name) + { + var sections = this.Sections; + for (int i = 0; i < sections.Length; i++) { + var section = sections [i]; + if (section.Name == name) + return section; + } + + return null; + } + + public Section GetSectionAtVirtualAddress (RVA rva) + { + var sections = this.Sections; + for (int i = 0; i < sections.Length; i++) { + var section = sections [i]; + if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.SizeOfRawData) + return section; + } + + return null; + } + + BinaryStreamReader GetReaderAt (RVA rva) + { + var section = GetSectionAtVirtualAddress (rva); + if (section == null) + return null; + + var reader = new BinaryStreamReader (Stream.value); + reader.MoveTo (ResolveVirtualAddressInSection (rva, section)); + return reader; + } + + public TRet GetReaderAt (RVA rva, TItem item, Func read) where TRet : class + { + var position = Stream.value.Position; + try { + var reader = GetReaderAt (rva); + if (reader == null) + return null; + + return read (item, reader); + } finally { + Stream.value.Position = position; + } + } + + 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); + } + + public void Dispose () + { + Stream.Dispose (); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.PE/ImageReader.cs b/Mono.Cecil.20/Mono.Cecil.PE/ImageReader.cs new file mode 100644 index 00000000..f36d2e5a --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.PE/ImageReader.cs @@ -0,0 +1,783 @@ +// +// 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.IO; + +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Collections.Generic; + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + sealed class ImageReader : BinaryStreamReader { + + readonly Image image; + + DataDirectory cli; + DataDirectory metadata; + + uint table_heap_offset; + + public ImageReader (Disposable stream, string file_name) + : base (stream.value) + { + image = new Image (); + image.Stream = stream; + image.FileName = file_name; + } + + void MoveTo (DataDirectory directory) + { + BaseStream.Position = image.ResolveVirtualAddress (directory.VirtualAddress); + } + + void ReadImage () + { + if (BaseStream.Length < 128) + throw new BadImageFormatException (); + + // - DOSHeader + + // PE 2 + // Start 58 + // Lfanew 4 + // End 64 + + if (ReadUInt16 () != 0x5a4d) + throw new BadImageFormatException (); + + Advance (58); + + MoveTo (ReadUInt32 ()); + + if (ReadUInt32 () != 0x00004550) + throw new BadImageFormatException (); + + // - PEFileHeader + + // Machine 2 + image.Architecture = ReadArchitecture (); + + // NumberOfSections 2 + ushort sections = ReadUInt16 (); + + // TimeDateStamp 4 + image.Timestamp = ReadUInt32 (); + // PointerToSymbolTable 4 + // NumberOfSymbols 4 + // OptionalHeaderSize 2 + Advance (10); + + // Characteristics 2 + ushort characteristics = ReadUInt16 (); + + ushort subsystem, dll_characteristics; + ReadOptionalHeaders (out subsystem, out dll_characteristics); + ReadSections (sections); + ReadCLIHeader (); + ReadMetadata (); + ReadDebugHeader (); + + image.Kind = GetModuleKind (characteristics, subsystem); + image.Characteristics = (ModuleCharacteristics) dll_characteristics; + } + + TargetArchitecture ReadArchitecture () + { + return (TargetArchitecture) ReadUInt16 (); + } + + static ModuleKind GetModuleKind (ushort characteristics, ushort subsystem) + { + if ((characteristics & 0x2000) != 0) // ImageCharacteristics.Dll + return ModuleKind.Dll; + + if (subsystem == 0x2 || subsystem == 0x9) // SubSystem.WindowsGui || SubSystem.WindowsCeGui + return ModuleKind.Windows; + + return ModuleKind.Console; + } + + void ReadOptionalHeaders (out ushort subsystem, out ushort dll_characteristics) + { + // - PEOptionalHeader + // - StandardFieldsHeader + + // Magic 2 + bool pe64 = ReadUInt16 () == 0x20b; + + // pe32 || pe64 + + // LMajor 1 + // LMinor 1 + // CodeSize 4 + // InitializedDataSize 4 + // UninitializedDataSize4 + // EntryPointRVA 4 + // BaseOfCode 4 + // BaseOfData 4 || 0 + + // - NTSpecificFieldsHeader + + // ImageBase 4 || 8 + // SectionAlignment 4 + // FileAlignement 4 + // OSMajor 2 + // OSMinor 2 + // UserMajor 2 + // UserMinor 2 + // SubSysMajor 2 + // SubSysMinor 2 + // Reserved 4 + // ImageSize 4 + // HeaderSize 4 + // FileChecksum 4 + Advance (66); + + // SubSystem 2 + subsystem = ReadUInt16 (); + + // DLLFlags 2 + dll_characteristics = ReadUInt16 (); + // StackReserveSize 4 || 8 + // StackCommitSize 4 || 8 + // HeapReserveSize 4 || 8 + // HeapCommitSize 4 || 8 + // LoaderFlags 4 + // NumberOfDataDir 4 + + // - DataDirectoriesHeader + + // ExportTable 8 + // ImportTable 8 + // ResourceTable 8 + // ExceptionTable 8 + // CertificateTable 8 + // BaseRelocationTable 8 + + Advance (pe64 ? 88 : 72); + + // Debug 8 + image.Debug = ReadDataDirectory (); + + // Copyright 8 + // GlobalPtr 8 + // TLSTable 8 + // LoadConfigTable 8 + // BoundImport 8 + // IAT 8 + // DelayImportDescriptor8 + Advance (56); + + // CLIHeader 8 + cli = ReadDataDirectory (); + + if (cli.IsZero) + throw new BadImageFormatException (); + + // Reserved 8 + Advance (8); + } + + string ReadAlignedString (int length) + { + int read = 0; + var buffer = new char [length]; + while (read < length) { + var current = ReadByte (); + if (current == 0) + break; + + buffer [read++] = (char) current; + } + + Advance (-1 + ((read + 4) & ~3) - read); + + return new string (buffer, 0, read); + } + + string ReadZeroTerminatedString (int length) + { + int read = 0; + var buffer = new char [length]; + var bytes = ReadBytes (length); + while (read < length) { + var current = bytes [read]; + if (current == 0) + break; + + buffer [read++] = (char) current; + } + + return new string (buffer, 0, read); + } + + void ReadSections (ushort count) + { + var sections = new Section [count]; + + for (int i = 0; i < count; i++) { + var section = new Section (); + + // Name + section.Name = ReadZeroTerminatedString (8); + + // VirtualSize 4 + Advance (4); + + // VirtualAddress 4 + section.VirtualAddress = ReadUInt32 (); + // SizeOfRawData 4 + section.SizeOfRawData = ReadUInt32 (); + // PointerToRawData 4 + section.PointerToRawData = ReadUInt32 (); + + // PointerToRelocations 4 + // PointerToLineNumbers 4 + // NumberOfRelocations 2 + // NumberOfLineNumbers 2 + // Characteristics 4 + Advance (16); + + sections [i] = section; + } + + image.Sections = sections; + } + + void ReadCLIHeader () + { + MoveTo (cli); + + // - CLIHeader + + // Cb 4 + // MajorRuntimeVersion 2 + // MinorRuntimeVersion 2 + Advance (8); + + // Metadata 8 + metadata = ReadDataDirectory (); + // Flags 4 + image.Attributes = (ModuleAttributes) ReadUInt32 (); + // EntryPointToken 4 + image.EntryPointToken = ReadUInt32 (); + // Resources 8 + image.Resources = ReadDataDirectory (); + // StrongNameSignature 8 + image.StrongName = ReadDataDirectory (); + // CodeManagerTable 8 + // VTableFixups 8 + // ExportAddressTableJumps 8 + // ManagedNativeHeader 8 + } + + void ReadMetadata () + { + MoveTo (metadata); + + if (ReadUInt32 () != 0x424a5342) + throw new BadImageFormatException (); + + // MajorVersion 2 + // MinorVersion 2 + // Reserved 4 + Advance (8); + + image.RuntimeVersion = ReadZeroTerminatedString (ReadInt32 ()); + + // Flags 2 + Advance (2); + + var streams = ReadUInt16 (); + + var section = image.GetSectionAtVirtualAddress (metadata.VirtualAddress); + if (section == null) + throw new BadImageFormatException (); + + image.MetadataSection = section; + + for (int i = 0; i < streams; i++) + ReadMetadataStream (section); + + if (image.PdbHeap != null) + ReadPdbHeap (); + + if (image.TableHeap != null) + ReadTableHeap (); + } + + void ReadDebugHeader () + { + if (image.Debug.IsZero) { + image.DebugHeader = new ImageDebugHeader (Empty.Array); + return; + } + + MoveTo (image.Debug); + + var entries = new ImageDebugHeaderEntry [(int) image.Debug.Size / ImageDebugDirectory.Size]; + + for (int i = 0; i < entries.Length; i++) { + var directory = new ImageDebugDirectory { + Characteristics = ReadInt32 (), + TimeDateStamp = ReadInt32 (), + MajorVersion = ReadInt16 (), + MinorVersion = ReadInt16 (), + Type = (ImageDebugType) ReadInt32 (), + SizeOfData = ReadInt32 (), + AddressOfRawData = ReadInt32 (), + PointerToRawData = ReadInt32 (), + }; + + if (directory.AddressOfRawData == 0) { + entries [i] = new ImageDebugHeaderEntry (directory, Empty.Array); + continue; + } + + var position = Position; + try { + MoveTo ((uint) directory.PointerToRawData); + var data = ReadBytes (directory.SizeOfData); + entries [i] = new ImageDebugHeaderEntry (directory, data); + } finally { + Position = position; + } + } + + image.DebugHeader = new ImageDebugHeader (entries); + } + + void ReadMetadataStream (Section section) + { + // Offset 4 + 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 (data); + table_heap_offset = offset; + break; + case "#Strings": + image.StringHeap = new StringHeap (data); + break; + case "#Blob": + image.BlobHeap = new BlobHeap (data); + break; + case "#GUID": + image.GuidHeap = new GuidHeap (data); + break; + case "#US": + image.UserStringHeap = new UserStringHeap (data); + break; + case "#Pdb": + 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; + + MoveTo (table_heap_offset + image.MetadataSection.PointerToRawData); + + // Reserved 4 + // MajorVersion 1 + // MinorVersion 1 + Advance (6); + + // HeapSizes 1 + var sizes = ReadByte (); + + // Reserved2 1 + Advance (1); + + // Valid 8 + heap.Valid = ReadInt64 (); + + // Sorted 8 + heap.Sorted = ReadInt64 (); + + if (image.PdbHeap != null) { + for (int i = 0; i < Mixin.TableCount; i++) { + if (!image.PdbHeap.HasTable ((Table) i)) + continue; + + heap.Tables [i].Length = image.PdbHeap.TypeSystemTableRows [i]; + } + } + + for (int i = 0; i < Mixin.TableCount; i++) { + if (!heap.HasTable ((Table) i)) + continue; + + heap.Tables [i].Length = ReadUInt32 (); + } + + SetIndexSize (image.StringHeap, sizes, 0x1); + SetIndexSize (image.GuidHeap, sizes, 0x2); + SetIndexSize (image.BlobHeap, sizes, 0x4); + + ComputeTableInformations (); + } + + static void SetIndexSize (Heap heap, uint sizes, byte flag) + { + if (heap == null) + return; + + heap.IndexSize = (sizes & flag) > 0 ? 4 : 2; + } + + int GetTableIndexSize (Table table) + { + return image.GetTableIndexSize (table); + } + + int GetCodedIndexSize (CodedIndex index) + { + return image.GetCodedIndexSize (index); + } + + void ComputeTableInformations () + { + uint offset = (uint) BaseStream.Position - table_heap_offset - image.MetadataSection.PointerToRawData; // header + + int stridx_size = image.StringHeap.IndexSize; + int guididx_size = image.GuidHeap != null ? image.GuidHeap.IndexSize : 2; + int blobidx_size = image.BlobHeap != null ? image.BlobHeap.IndexSize : 2; + + var heap = image.TableHeap; + var tables = heap.Tables; + + for (int i = 0; i < Mixin.TableCount; i++) { + var table = (Table) i; + if (!heap.HasTable (table)) + continue; + + int size; + switch (table) { + case Table.Module: + size = 2 // Generation + + stridx_size // Name + + (guididx_size * 3); // Mvid, EncId, EncBaseId + break; + case Table.TypeRef: + size = GetCodedIndexSize (CodedIndex.ResolutionScope) // ResolutionScope + + (stridx_size * 2); // Name, Namespace + break; + case Table.TypeDef: + size = 4 // Flags + + (stridx_size * 2) // Name, Namespace + + GetCodedIndexSize (CodedIndex.TypeDefOrRef) // BaseType + + GetTableIndexSize (Table.Field) // FieldList + + GetTableIndexSize (Table.Method); // MethodList + break; + case Table.FieldPtr: + size = GetTableIndexSize (Table.Field); // Field + break; + case Table.Field: + size = 2 // Flags + + stridx_size // Name + + blobidx_size; // Signature + break; + case Table.MethodPtr: + size = GetTableIndexSize (Table.Method); // Method + break; + case Table.Method: + size = 8 // Rva 4, ImplFlags 2, Flags 2 + + stridx_size // Name + + blobidx_size // Signature + + GetTableIndexSize (Table.Param); // ParamList + break; + case Table.ParamPtr: + size = GetTableIndexSize (Table.Param); // Param + break; + case Table.Param: + size = 4 // Flags 2, Sequence 2 + + stridx_size; // Name + break; + case Table.InterfaceImpl: + size = GetTableIndexSize (Table.TypeDef) // Class + + GetCodedIndexSize (CodedIndex.TypeDefOrRef); // Interface + break; + case Table.MemberRef: + size = GetCodedIndexSize (CodedIndex.MemberRefParent) // Class + + stridx_size // Name + + blobidx_size; // Signature + break; + case Table.Constant: + size = 2 // Type + + GetCodedIndexSize (CodedIndex.HasConstant) // Parent + + blobidx_size; // Value + break; + case Table.CustomAttribute: + size = GetCodedIndexSize (CodedIndex.HasCustomAttribute) // Parent + + GetCodedIndexSize (CodedIndex.CustomAttributeType) // Type + + blobidx_size; // Value + break; + case Table.FieldMarshal: + size = GetCodedIndexSize (CodedIndex.HasFieldMarshal) // Parent + + blobidx_size; // NativeType + break; + case Table.DeclSecurity: + size = 2 // Action + + GetCodedIndexSize (CodedIndex.HasDeclSecurity) // Parent + + blobidx_size; // PermissionSet + break; + case Table.ClassLayout: + size = 6 // PackingSize 2, ClassSize 4 + + GetTableIndexSize (Table.TypeDef); // Parent + break; + case Table.FieldLayout: + size = 4 // Offset + + GetTableIndexSize (Table.Field); // Field + break; + case Table.StandAloneSig: + size = blobidx_size; // Signature + break; + case Table.EventMap: + size = GetTableIndexSize (Table.TypeDef) // Parent + + GetTableIndexSize (Table.Event); // EventList + break; + case Table.EventPtr: + size = GetTableIndexSize (Table.Event); // Event + break; + case Table.Event: + size = 2 // Flags + + stridx_size // Name + + GetCodedIndexSize (CodedIndex.TypeDefOrRef); // EventType + break; + case Table.PropertyMap: + size = GetTableIndexSize (Table.TypeDef) // Parent + + GetTableIndexSize (Table.Property); // PropertyList + break; + case Table.PropertyPtr: + size = GetTableIndexSize (Table.Property); // Property + break; + case Table.Property: + size = 2 // Flags + + stridx_size // Name + + blobidx_size; // Type + break; + case Table.MethodSemantics: + size = 2 // Semantics + + GetTableIndexSize (Table.Method) // Method + + GetCodedIndexSize (CodedIndex.HasSemantics); // Association + break; + case Table.MethodImpl: + size = GetTableIndexSize (Table.TypeDef) // Class + + GetCodedIndexSize (CodedIndex.MethodDefOrRef) // MethodBody + + GetCodedIndexSize (CodedIndex.MethodDefOrRef); // MethodDeclaration + break; + case Table.ModuleRef: + size = stridx_size; // Name + break; + case Table.TypeSpec: + size = blobidx_size; // Signature + break; + case Table.ImplMap: + size = 2 // MappingFlags + + GetCodedIndexSize (CodedIndex.MemberForwarded) // MemberForwarded + + stridx_size // ImportName + + GetTableIndexSize (Table.ModuleRef); // ImportScope + break; + case Table.FieldRVA: + size = 4 // RVA + + GetTableIndexSize (Table.Field); // Field + break; + case Table.EncLog: + size = 8; + break; + case Table.EncMap: + size = 4; + break; + case Table.Assembly: + size = 16 // HashAlgId 4, Version 4 * 2, Flags 4 + + blobidx_size // PublicKey + + (stridx_size * 2); // Name, Culture + break; + case Table.AssemblyProcessor: + size = 4; // Processor + break; + case Table.AssemblyOS: + size = 12; // Platform 4, Version 2 * 4 + break; + case Table.AssemblyRef: + size = 12 // Version 2 * 4 + Flags 4 + + (blobidx_size * 2) // PublicKeyOrToken, HashValue + + (stridx_size * 2); // Name, Culture + break; + case Table.AssemblyRefProcessor: + size = 4 // Processor + + GetTableIndexSize (Table.AssemblyRef); // AssemblyRef + break; + case Table.AssemblyRefOS: + size = 12 // Platform 4, Version 2 * 4 + + GetTableIndexSize (Table.AssemblyRef); // AssemblyRef + break; + case Table.File: + size = 4 // Flags + + stridx_size // Name + + blobidx_size; // HashValue + break; + case Table.ExportedType: + size = 8 // Flags 4, TypeDefId 4 + + (stridx_size * 2) // Name, Namespace + + GetCodedIndexSize (CodedIndex.Implementation); // Implementation + break; + case Table.ManifestResource: + size = 8 // Offset, Flags + + stridx_size // Name + + GetCodedIndexSize (CodedIndex.Implementation); // Implementation + break; + case Table.NestedClass: + size = GetTableIndexSize (Table.TypeDef) // NestedClass + + GetTableIndexSize (Table.TypeDef); // EnclosingClass + break; + case Table.GenericParam: + size = 4 // Number, Flags + + GetCodedIndexSize (CodedIndex.TypeOrMethodDef) // Owner + + stridx_size; // Name + break; + case Table.MethodSpec: + size = GetCodedIndexSize (CodedIndex.MethodDefOrRef) // Method + + blobidx_size; // Instantiation + break; + case Table.GenericParamConstraint: + 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 (); + } + + tables [i].RowSize = (uint) size; + tables [i].Offset = offset; + + offset += (uint) size * tables [i].Length; + } + } + + void ReadPdbHeap () + { + var heap = image.PdbHeap; + + var buffer = new ByteBuffer (heap.data); + + 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++) { + var table = (Table) i; + if (!heap.HasTable (table)) + continue; + + heap.TypeSystemTableRows [i] = buffer.ReadUInt32 (); + } + } + + public static Image ReadImage (Disposable stream, string file_name) + { + try { + var reader = new ImageReader (stream, file_name); + reader.ReadImage (); + return reader.image; + } catch (EndOfStreamException e) { + throw new BadImageFormatException (stream.value.GetFileName (), e); + } + } + + public static Image ReadPortablePdb (Disposable stream, string file_name) + { + try { + var reader = new ImageReader (stream, file_name); + var length = (uint) stream.value.Length; + + reader.image.Sections = new[] { + new Section { + PointerToRawData = 0, + SizeOfRawData = length, + VirtualAddress = 0, + VirtualSize = length, + } + }; + + reader.metadata = new DataDirectory (0, length); + reader.ReadMetadata (); + return reader.image; + } catch (EndOfStreamException e) { + throw new BadImageFormatException (stream.value.GetFileName (), e); + } + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.PE/ImageWriter.cs b/Mono.Cecil.20/Mono.Cecil.PE/ImageWriter.cs new file mode 100644 index 00000000..3fc689d2 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.PE/ImageWriter.cs @@ -0,0 +1,857 @@ +// +// 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.IO; + +#if !READ_ONLY + +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + sealed class ImageWriter : BinaryStreamWriter { + + readonly ModuleDefinition module; + readonly MetadataBuilder metadata; + readonly TextMap text_map; + readonly internal Disposable stream; + + readonly string runtime_version; + + ImageDebugHeader debug_header; + + ByteBuffer win32_resources; + + const uint pe_header_size = 0x98u; + const uint section_header_size = 0x28u; + const uint file_alignment = 0x200; + const uint section_alignment = 0x2000; + const ulong image_base = 0x00400000; + + internal const RVA text_rva = 0x2000; + + readonly bool pe64; + readonly bool has_reloc; + + internal Section text; + internal Section rsrc; + internal Section reloc; + + ushort sections; + + ImageWriter (ModuleDefinition module, string runtime_version, MetadataBuilder metadata, Disposable stream, bool metadataOnly = false) + : base (stream.value) + { + this.module = module; + this.runtime_version = runtime_version; + this.text_map = metadata.text_map; + this.stream = stream; + this.metadata = metadata; + if (metadataOnly) + return; + + this.pe64 = module.Architecture == TargetArchitecture.AMD64 || module.Architecture == TargetArchitecture.IA64 || module.Architecture == TargetArchitecture.ARM64; + this.has_reloc = module.Architecture == TargetArchitecture.I386; + this.GetDebugHeader (); + this.GetWin32Resources (); + this.BuildTextMap (); + this.sections = (ushort) (has_reloc ? 2 : 1); // text + reloc? + } + + void GetDebugHeader () + { + var symbol_writer = metadata.symbol_writer; + if (symbol_writer != null) + debug_header = symbol_writer.GetDebugHeader (); + + if (module.HasDebugHeader) { + var header = module.GetDebugHeader (); + var deterministic = header.GetDeterministicEntry (); + if (deterministic == null) + return; + + debug_header = debug_header.AddDeterministicEntry (); + } + } + + void GetWin32Resources () + { + var rsrc = GetImageResourceSection (); + if (rsrc == null) + return; + + win32_resources = module.Image.GetReaderAt (rsrc.VirtualAddress, rsrc.SizeOfRawData, (s, reader) => new ByteBuffer (reader.ReadBytes ((int) s))); + } + + Section GetImageResourceSection () + { + if (!module.HasImage) + return null; + + const string rsrc_section = ".rsrc"; + + return module.Image.GetSection (rsrc_section); + } + + public static ImageWriter CreateWriter (ModuleDefinition module, MetadataBuilder metadata, Disposable stream) + { + var writer = new ImageWriter (module, module.runtime_version, metadata, stream); + writer.BuildSections (); + return writer; + } + + public static ImageWriter CreateDebugWriter (ModuleDefinition module, MetadataBuilder metadata, Disposable 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; + if (has_win32_resources) + sections++; + + text = CreateSection (".text", text_map.GetLength (), null); + var previous = text; + + if (has_win32_resources) { + rsrc = CreateSection (".rsrc", (uint) win32_resources.length, previous); + + PatchWin32Resources (win32_resources); + previous = rsrc; + } + + if (has_reloc) + reloc = CreateSection (".reloc", 12u, previous); + } + + Section CreateSection (string name, uint size, Section previous) + { + return new Section { + Name = name, + VirtualAddress = previous != null + ? previous.VirtualAddress + Align (previous.VirtualSize, section_alignment) + : text_rva, + VirtualSize = size, + PointerToRawData = previous != null + ? previous.PointerToRawData + previous.SizeOfRawData + : Align (GetHeaderSize (), file_alignment), + SizeOfRawData = Align (size, file_alignment) + }; + } + + static uint Align (uint value, uint align) + { + align--; + return (value + align) & ~align; + } + + void WriteDOSHeader () + { + Write (new byte [] { + // dos header start + 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + // lfanew + 0x80, 0x00, 0x00, 0x00, + // dos header end + 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, + 0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, + 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 0x63, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, + 0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, + 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, 0x6d, + 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }); + } + + ushort SizeOfOptionalHeader () + { + return (ushort) (!pe64 ? 0xe0 : 0xf0); + } + + void WritePEFileHeader () + { + WriteUInt32 (0x00004550); // Magic + WriteUInt16 ((ushort) module.Architecture); // Machine + WriteUInt16 (sections); // NumberOfSections + WriteUInt32 (metadata.timestamp); + WriteUInt32 (0); // PointerToSymbolTable + WriteUInt32 (0); // NumberOfSymbols + WriteUInt16 (SizeOfOptionalHeader ()); // SizeOfOptionalHeader + + // ExecutableImage | (pe64 ? 32BitsMachine : LargeAddressAware) + var characteristics = (ushort) (0x0002 | (!pe64 ? 0x0100 : 0x0020)); + if (module.Kind == ModuleKind.Dll || module.Kind == ModuleKind.NetModule) + characteristics |= 0x2000; + WriteUInt16 (characteristics); // Characteristics + } + + Section LastSection () + { + if (reloc != null) + return reloc; + + if (rsrc != null) + return rsrc; + + return text; + } + + void WriteOptionalHeaders () + { + WriteUInt16 ((ushort) (!pe64 ? 0x10b : 0x20b)); // Magic + WriteByte (8); // LMajor + WriteByte (0); // LMinor + WriteUInt32 (text.SizeOfRawData); // CodeSize + WriteUInt32 ((reloc != null ? reloc.SizeOfRawData : 0) + + (rsrc != null ? rsrc.SizeOfRawData : 0)); // InitializedDataSize + WriteUInt32 (0); // UninitializedDataSize + + var startub_stub = text_map.GetRange (TextSegment.StartupStub); + WriteUInt32 (startub_stub.Length > 0 ? startub_stub.Start : 0); // EntryPointRVA + WriteUInt32 (text_rva); // BaseOfCode + + if (!pe64) { + WriteUInt32 (0); // BaseOfData + WriteUInt32 ((uint) image_base); // ImageBase + } else { + WriteUInt64 (image_base); // ImageBase + } + + WriteUInt32 (section_alignment); // SectionAlignment + WriteUInt32 (file_alignment); // FileAlignment + + WriteUInt16 (4); // OSMajor + WriteUInt16 (0); // OSMinor + WriteUInt16 (0); // UserMajor + WriteUInt16 (0); // UserMinor + WriteUInt16 (4); // SubSysMajor + WriteUInt16 (0); // SubSysMinor + WriteUInt32 (0); // Reserved + + var last_section = LastSection(); + WriteUInt32 (last_section.VirtualAddress + Align (last_section.VirtualSize, section_alignment)); // ImageSize + WriteUInt32 (text.PointerToRawData); // HeaderSize + + WriteUInt32 (0); // Checksum + WriteUInt16 (GetSubSystem ()); // SubSystem + WriteUInt16 ((ushort) module.Characteristics); // DLLFlags + + const ulong stack_reserve = 0x100000; + const ulong stack_commit = 0x1000; + const ulong heap_reserve = 0x100000; + const ulong heap_commit = 0x1000; + + if (!pe64) { + WriteUInt32 ((uint) stack_reserve); + WriteUInt32 ((uint) stack_commit); + WriteUInt32 ((uint) heap_reserve); + WriteUInt32 ((uint) heap_commit); + } else { + WriteUInt64 (stack_reserve); + WriteUInt64 (stack_commit); + WriteUInt64 (heap_reserve); + WriteUInt64 (heap_commit); + } + + WriteUInt32 (0); // LoaderFlags + WriteUInt32 (16); // NumberOfDataDir + + WriteZeroDataDirectory (); // ExportTable + WriteDataDirectory (text_map.GetDataDirectory (TextSegment.ImportDirectory)); // ImportTable + if (rsrc != null) { // ResourceTable + WriteUInt32 (rsrc.VirtualAddress); + WriteUInt32 (rsrc.VirtualSize); + } else + WriteZeroDataDirectory (); + + WriteZeroDataDirectory (); // ExceptionTable + WriteZeroDataDirectory (); // CertificateTable + WriteUInt32 (reloc != null ? reloc.VirtualAddress : 0); // BaseRelocationTable + WriteUInt32 (reloc != null ? reloc.VirtualSize : 0); + + if (text_map.GetLength (TextSegment.DebugDirectory) > 0) { + WriteUInt32 (text_map.GetRVA (TextSegment.DebugDirectory)); + WriteUInt32 ((uint) (debug_header.Entries.Length * ImageDebugDirectory.Size)); + } else + WriteZeroDataDirectory (); + + WriteZeroDataDirectory (); // Copyright + WriteZeroDataDirectory (); // GlobalPtr + WriteZeroDataDirectory (); // TLSTable + WriteZeroDataDirectory (); // LoadConfigTable + WriteZeroDataDirectory (); // BoundImport + WriteDataDirectory (text_map.GetDataDirectory (TextSegment.ImportAddressTable)); // IAT + WriteZeroDataDirectory (); // DelayImportDesc + WriteDataDirectory (text_map.GetDataDirectory (TextSegment.CLIHeader)); // CLIHeader + WriteZeroDataDirectory (); // Reserved + } + + void WriteZeroDataDirectory () + { + WriteUInt32 (0); + WriteUInt32 (0); + } + + ushort GetSubSystem () + { + switch (module.Kind) { + case ModuleKind.Console: + case ModuleKind.Dll: + case ModuleKind.NetModule: + return 0x3; + case ModuleKind.Windows: + return 0x2; + default: + throw new ArgumentOutOfRangeException (); + } + } + + void WriteSectionHeaders () + { + WriteSection (text, 0x60000020); + + if (rsrc != null) + WriteSection (rsrc, 0x40000040); + + if (reloc != null) + WriteSection (reloc, 0x42000040); + } + + void WriteSection (Section section, uint characteristics) + { + var name = new byte [8]; + var sect_name = section.Name; + for (int i = 0; i < sect_name.Length; i++) + name [i] = (byte) sect_name [i]; + + WriteBytes (name); + WriteUInt32 (section.VirtualSize); + WriteUInt32 (section.VirtualAddress); + WriteUInt32 (section.SizeOfRawData); + WriteUInt32 (section.PointerToRawData); + WriteUInt32 (0); // PointerToRelocations + WriteUInt32 (0); // PointerToLineNumbers + WriteUInt16 (0); // NumberOfRelocations + WriteUInt16 (0); // NumberOfLineNumbers + WriteUInt32 (characteristics); + } + + void MoveTo (uint pointer) + { + BaseStream.Seek (pointer, SeekOrigin.Begin); + } + + void MoveToRVA (Section section, RVA rva) + { + BaseStream.Seek (section.PointerToRawData + rva - section.VirtualAddress, SeekOrigin.Begin); + } + + void MoveToRVA (TextSegment segment) + { + MoveToRVA (text, text_map.GetRVA (segment)); + } + + void WriteRVA (RVA rva) + { + if (!pe64) + WriteUInt32 (rva); + else + WriteUInt64 (rva); + } + + void PrepareSection (Section section) + { + MoveTo (section.PointerToRawData); + + const int buffer_size = 4096; + + if (section.SizeOfRawData <= buffer_size) { + Write (new byte [section.SizeOfRawData]); + MoveTo (section.PointerToRawData); + return; + } + + var written = 0; + var buffer = new byte [buffer_size]; + while (written != section.SizeOfRawData) { + var write_size = System.Math.Min((int) section.SizeOfRawData - written, buffer_size); + Write (buffer, 0, write_size); + written += write_size; + } + + MoveTo (section.PointerToRawData); + } + + void WriteText () + { + PrepareSection (text); + + // ImportAddressTable + + if (has_reloc) { + WriteRVA (text_map.GetRVA (TextSegment.ImportHintNameTable)); + WriteRVA (0); + } + + // CLIHeader + + WriteUInt32 (0x48); + WriteUInt16 (2); + WriteUInt16 ((ushort) ((module.Runtime <= TargetRuntime.Net_1_1) ? 0 : 5)); + + WriteUInt32 (text_map.GetRVA (TextSegment.MetadataHeader)); + WriteUInt32 (GetMetadataLength ()); + WriteUInt32 ((uint) module.Attributes); + WriteUInt32 (metadata.entry_point.ToUInt32 ()); + WriteDataDirectory (text_map.GetDataDirectory (TextSegment.Resources)); + WriteDataDirectory (text_map.GetDataDirectory (TextSegment.StrongNameSignature)); + WriteZeroDataDirectory (); // CodeManagerTable + WriteZeroDataDirectory (); // VTableFixups + WriteZeroDataDirectory (); // ExportAddressTableJumps + WriteZeroDataDirectory (); // ManagedNativeHeader + + // Code + + MoveToRVA (TextSegment.Code); + WriteBuffer (metadata.code); + + // Resources + + MoveToRVA (TextSegment.Resources); + WriteBuffer (metadata.resources); + + // Data + + if (metadata.data.length > 0) { + MoveToRVA (TextSegment.Data); + WriteBuffer (metadata.data); + } + + // StrongNameSignature + // stays blank + + // MetadataHeader + + MoveToRVA (TextSegment.MetadataHeader); + WriteMetadataHeader (); + + WriteMetadata (); + + // DebugDirectory + if (text_map.GetLength (TextSegment.DebugDirectory) > 0) { + MoveToRVA (TextSegment.DebugDirectory); + WriteDebugDirectory (); + } + + if (!has_reloc) + return; + + // ImportDirectory + MoveToRVA (TextSegment.ImportDirectory); + WriteImportDirectory (); + + // StartupStub + MoveToRVA (TextSegment.StartupStub); + WriteStartupStub (); + } + + uint GetMetadataLength () + { + return text_map.GetRVA (TextSegment.DebugDirectory) - text_map.GetRVA (TextSegment.MetadataHeader); + } + + public void WriteMetadataHeader () + { + WriteUInt32 (0x424a5342); // Signature + WriteUInt16 (1); // MajorVersion + WriteUInt16 (1); // MinorVersion + WriteUInt32 (0); // Reserved + + var version = GetZeroTerminatedString (runtime_version); + WriteUInt32 ((uint) version.Length); + WriteBytes (version); + WriteUInt16 (0); // Flags + WriteUInt16 (GetStreamCount ()); + + uint offset = text_map.GetRVA (TextSegment.TableHeap) - text_map.GetRVA (TextSegment.MetadataHeader); + + WriteStreamHeader (ref offset, TextSegment.TableHeap, "#~"); + WriteStreamHeader (ref offset, TextSegment.StringHeap, "#Strings"); + 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 () + { + return (ushort) ( + 1 // #~ + + 1 // #Strings + + (metadata.user_string_heap.IsEmpty ? 0 : 1) // #US + + (metadata.guid_heap.IsEmpty ? 0 : 1) // GUID + + (metadata.blob_heap.IsEmpty ? 0 : 1) + + (metadata.pdb_heap == null ? 0 : 1)); // #Blob + } + + void WriteStreamHeader (ref uint offset, TextSegment heap, string name) + { + var length = (uint) text_map.GetLength (heap); + if (length == 0) + return; + + WriteUInt32 (offset); + WriteUInt32 (length); + WriteBytes (GetZeroTerminatedString (name)); + offset += length; + } + + static int GetZeroTerminatedStringLength (string @string) + { + return (@string.Length + 1 + 3) & ~3; + } + + static byte [] GetZeroTerminatedString (string @string) + { + return GetString (@string, GetZeroTerminatedStringLength (@string)); + } + + static byte [] GetSimpleString (string @string) + { + return GetString (@string, @string.Length); + } + + static byte [] GetString (string @string, int length) + { + var bytes = new byte [length]; + for (int i = 0; i < @string.Length; i++) + bytes [i] = (byte) @string [i]; + + return bytes; + } + + public void WriteMetadata () + { + WriteHeap (TextSegment.TableHeap, metadata.table_heap); + WriteHeap (TextSegment.StringHeap, metadata.string_heap); + WriteHeap (TextSegment.UserStringHeap, metadata.user_string_heap); + 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 == null || buffer.IsEmpty) + return; + + MoveToRVA (heap); + WriteBuffer (buffer); + } + + void WriteDebugDirectory () + { + var data_start = (int) BaseStream.Position + (debug_header.Entries.Length * ImageDebugDirectory.Size); + + for (var i = 0; i < debug_header.Entries.Length; i++) { + var entry = debug_header.Entries [i]; + var directory = entry.Directory; + WriteInt32 (directory.Characteristics); + WriteInt32 (directory.TimeDateStamp); + WriteInt16 (directory.MajorVersion); + WriteInt16 (directory.MinorVersion); + WriteInt32 ((int) directory.Type); + WriteInt32 (directory.SizeOfData); + WriteInt32 (directory.AddressOfRawData); + WriteInt32 (data_start); + + data_start += entry.Data.Length; + } + + for (var i = 0; i < debug_header.Entries.Length; i++) { + var entry = debug_header.Entries [i]; + WriteBytes (entry.Data); + } + } + + void WriteImportDirectory () + { + WriteUInt32 (text_map.GetRVA (TextSegment.ImportDirectory) + 40); // ImportLookupTable + WriteUInt32 (0); // DateTimeStamp + WriteUInt32 (0); // ForwarderChain + WriteUInt32 (text_map.GetRVA (TextSegment.ImportHintNameTable) + 14); + WriteUInt32 (text_map.GetRVA (TextSegment.ImportAddressTable)); + Advance (20); + + // ImportLookupTable + WriteUInt32 (text_map.GetRVA (TextSegment.ImportHintNameTable)); + + // ImportHintNameTable + MoveToRVA (TextSegment.ImportHintNameTable); + + WriteUInt16 (0); // Hint + WriteBytes (GetRuntimeMain ()); + WriteByte (0); + WriteBytes (GetSimpleString ("mscoree.dll")); + WriteUInt16 (0); + } + + byte [] GetRuntimeMain () + { + return module.Kind == ModuleKind.Dll || module.Kind == ModuleKind.NetModule + ? GetSimpleString ("_CorDllMain") + : GetSimpleString ("_CorExeMain"); + } + + void WriteStartupStub () + { + switch (module.Architecture) { + case TargetArchitecture.I386: + WriteUInt16 (0x25ff); + WriteUInt32 ((uint) image_base + text_map.GetRVA (TextSegment.ImportAddressTable)); + return; + default: + throw new NotSupportedException (); + } + } + + void WriteRsrc () + { + PrepareSection (rsrc); + WriteBuffer (win32_resources); + } + + void WriteReloc () + { + PrepareSection (reloc); + + var reloc_rva = text_map.GetRVA (TextSegment.StartupStub); + reloc_rva += module.Architecture == TargetArchitecture.IA64 ? 0x20u : 2; + var page_rva = reloc_rva & ~0xfffu; + + WriteUInt32 (page_rva); // PageRVA + WriteUInt32 (0x000c); // Block Size + + switch (module.Architecture) { + case TargetArchitecture.I386: + WriteUInt32 (0x3000 + reloc_rva - page_rva); + break; + default: + throw new NotSupportedException(); + } + } + + public void WriteImage () + { + WriteDOSHeader (); + WritePEFileHeader (); + WriteOptionalHeaders (); + WriteSectionHeaders (); + WriteText (); + if (rsrc != null) + WriteRsrc (); + if (reloc != null) + WriteReloc (); + Flush (); + } + + void BuildTextMap () + { + var map = text_map; + + map.AddMap (TextSegment.Code, metadata.code.length, !pe64 ? 4 : 16); + map.AddMap (TextSegment.Resources, metadata.resources.length, 8); + map.AddMap (TextSegment.Data, metadata.data.length, 4); + if (metadata.data.length > 0) + metadata.table_heap.FixupData (map.GetRVA (TextSegment.Data)); + map.AddMap (TextSegment.StrongNameSignature, GetStrongNameLength (), 4); + + BuildMetadataTextMap (); + + int debug_dir_len = 0; + if (debug_header != null && debug_header.HasEntries) { + var directories_len = debug_header.Entries.Length * ImageDebugDirectory.Size; + var data_address = (int) map.GetNextRVA (TextSegment.BlobHeap) + directories_len; + var data_len = 0; + + for (var i = 0; i < debug_header.Entries.Length; i++) { + var entry = debug_header.Entries [i]; + var directory = entry.Directory; + + directory.AddressOfRawData = entry.Data.Length == 0 ? 0 : data_address; + entry.Directory = directory; + + data_len += entry.Data.Length; + data_address += data_len; + } + + debug_dir_len = directories_len + data_len; + } + + map.AddMap (TextSegment.DebugDirectory, debug_dir_len, 4); + + if (!has_reloc) { + var start = map.GetNextRVA (TextSegment.DebugDirectory); + 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; + } + + RVA import_dir_rva = map.GetNextRVA (TextSegment.DebugDirectory); + RVA import_hnt_rva = import_dir_rva + 48u; + import_hnt_rva = (import_hnt_rva + 15u) & ~15u; + uint import_dir_len = (import_hnt_rva - import_dir_rva) + 27u; + + RVA startup_stub_rva = import_dir_rva + import_dir_len; + startup_stub_rva = module.Architecture == TargetArchitecture.IA64 + ? (startup_stub_rva + 15u) & ~15u + : 2 + ((startup_stub_rva + 3u) & ~3u); + + 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; + + 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 () + { + switch (module.Architecture) { + case TargetArchitecture.I386: + return 6; + default: + throw new NotSupportedException (); + } + } + + int GetMetadataHeaderLength (string runtimeVersion) + { + return + // MetadataHeader + 20 + GetZeroTerminatedStringLength (runtimeVersion) + // #~ header + + 12 + // #Strings header + + 20 + // #US header + + (metadata.user_string_heap.IsEmpty ? 0 : 12) + // #GUID header + + 16 + // #Blob header + + (metadata.blob_heap.IsEmpty ? 0 : 16) + // + + (metadata.pdb_heap == null ? 0 : 16); + } + + int GetStrongNameLength () + { + if (module.Assembly == null) + return 0; + + var public_key = module.Assembly.Name.PublicKey; + if (public_key.IsNullOrEmpty ()) + return 0; + + // in fx 2.0 the key may be from 384 to 16384 bits + // so we must calculate the signature size based on + // the size of the public key (minus the 32 byte header) + int size = public_key.Length; + if (size > 32) + return size - 32; + + // note: size == 16 for the ECMA "key" which is replaced + // by the runtime with a 1024 bits key (128 bytes) + + return 128; // default strongname signature size + } + + public DataDirectory GetStrongNameSignatureDirectory () + { + return text_map.GetDataDirectory (TextSegment.StrongNameSignature); + } + + public uint GetHeaderSize () + { + return pe_header_size + SizeOfOptionalHeader () + (sections * section_header_size); + } + + void PatchWin32Resources (ByteBuffer resources) + { + PatchResourceDirectoryTable (resources); + } + + void PatchResourceDirectoryTable (ByteBuffer resources) + { + resources.Advance (12); + + var entries = resources.ReadUInt16 () + resources.ReadUInt16 (); + + for (int i = 0; i < entries; i++) + PatchResourceDirectoryEntry (resources); + } + + void PatchResourceDirectoryEntry (ByteBuffer resources) + { + resources.Advance (4); + var child = resources.ReadUInt32 (); + + var position = resources.position; + resources.position = (int) child & 0x7fffffff; + + if ((child & 0x80000000) != 0) + PatchResourceDirectoryTable (resources); + else + PatchResourceDataEntry (resources); + + resources.position = position; + } + + void PatchResourceDataEntry (ByteBuffer resources) + { + var old_rsrc = GetImageResourceSection (); + var rva = resources.ReadUInt32 (); + resources.position -= 4; + resources.WriteUInt32 (rva - old_rsrc.VirtualAddress + rsrc.VirtualAddress); + } + } +} + +#endif diff --git a/Mono.Cecil.20/Mono.Cecil.PE/Section.cs b/Mono.Cecil.20/Mono.Cecil.PE/Section.cs new file mode 100644 index 00000000..49d8e900 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.PE/Section.cs @@ -0,0 +1,24 @@ +// +// 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 RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + sealed class Section { + public string Name; + public RVA VirtualAddress; + public uint VirtualSize; + public uint SizeOfRawData; + public uint PointerToRawData; + } +} diff --git a/Mono.Cecil.20/Mono.Cecil.PE/TextMap.cs b/Mono.Cecil.20/Mono.Cecil.PE/TextMap.cs new file mode 100644 index 00000000..614691b6 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.PE/TextMap.cs @@ -0,0 +1,112 @@ +// +// 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; + +#if !READ_ONLY + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + enum TextSegment { + ImportAddressTable, + CLIHeader, + Code, + Resources, + Data, + StrongNameSignature, + + // Metadata + MetadataHeader, + TableHeap, + StringHeap, + UserStringHeap, + GuidHeap, + BlobHeap, + PdbHeap, + // End Metadata + + DebugDirectory, + ImportDirectory, + ImportHintNameTable, + StartupStub, + } + + sealed class TextMap { + + readonly Range [] map = new Range [17 /*Enum.GetValues (typeof (TextSegment)).Length*/]; + + public void AddMap (TextSegment segment, int length) + { + map [(int) segment] = new Range (GetStart (segment), (uint) length); + } + + public void AddMap (TextSegment segment, int length, int align) + { + align--; + + AddMap (segment, (length + align) & ~align); + } + + public void AddMap (TextSegment segment, Range range) + { + map [(int) segment] = range; + } + + public Range GetRange (TextSegment segment) + { + return map [(int) segment]; + } + + public DataDirectory GetDataDirectory (TextSegment segment) + { + var range = map [(int) segment]; + + return new DataDirectory (range.Length == 0 ? 0 : range.Start, range.Length); + } + + public RVA GetRVA (TextSegment segment) + { + return map [(int) segment].Start; + } + + public RVA GetNextRVA (TextSegment segment) + { + var i = (int) segment; + return map [i].Start + map [i].Length; + } + + public int GetLength (TextSegment segment) + { + return (int) map [(int) segment].Length; + } + + RVA GetStart (TextSegment segment) + { + var index = (int) segment; + return index == 0 ? ImageWriter.text_rva : ComputeStart (index); + } + + RVA ComputeStart (int index) + { + index--; + return map [index].Start + map [index].Length; + } + + public uint GetLength () + { + var range = map [(int) TextSegment.StartupStub]; + return range.Start - ImageWriter.text_rva + range.Length; + } + } +} + +#endif diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ArrayType.cs b/Mono.Cecil.20/Mono.Cecil/ArrayType.cs similarity index 69% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/ArrayType.cs rename to Mono.Cecil.20/Mono.Cecil/ArrayType.cs index 55c59d87..010049cc 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ArrayType.cs +++ b/Mono.Cecil.20/Mono.Cecil/ArrayType.cs @@ -1,29 +1,11 @@ // -// ArrayType.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; diff --git a/Mono.Cecil.20/Mono.Cecil/AssemblyDefinition.cs b/Mono.Cecil.20/Mono.Cecil/AssemblyDefinition.cs new file mode 100644 index 00000000..f02b93f2 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/AssemblyDefinition.cs @@ -0,0 +1,194 @@ +// +// 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.IO; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class AssemblyDefinition : ICustomAttributeProvider, ISecurityDeclarationProvider, IDisposable { + + AssemblyNameDefinition name; + + internal ModuleDefinition main_module; + Collection modules; + Collection custom_attributes; + Collection security_declarations; + + public AssemblyNameDefinition Name { + get { return name; } + set { name = value; } + } + + public string FullName { + get { return name != null ? name.FullName : string.Empty; } + } + + public MetadataToken MetadataToken { + get { return new MetadataToken (TokenType.Assembly, 1); } + set { } + } + + public Collection Modules { + get { + if (modules != null) + return modules; + + if (main_module.HasImage) + return main_module.Read (ref modules, this, (_, reader) => reader.ReadModules ()); + + return modules = new Collection (1) { main_module }; + } + } + + public ModuleDefinition MainModule { + get { return main_module; } + } + + public MethodDefinition EntryPoint { + get { return main_module.EntryPoint; } + set { main_module.EntryPoint = value; } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return this.GetHasCustomAttributes (main_module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, main_module)); } + } + + public bool HasSecurityDeclarations { + get { + if (security_declarations != null) + return security_declarations.Count > 0; + + return this.GetHasSecurityDeclarations (main_module); + } + } + + public Collection SecurityDeclarations { + get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, main_module)); } + } + + internal AssemblyDefinition () + { + } + + 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) + { + return CreateAssembly (assemblyName, moduleName, new ModuleParameters { Kind = kind }); + } + + public static AssemblyDefinition CreateAssembly (AssemblyNameDefinition assemblyName, string moduleName, ModuleParameters parameters) + { + if (assemblyName == null) + throw new ArgumentNullException ("assemblyName"); + if (moduleName == null) + throw new ArgumentNullException ("moduleName"); + Mixin.CheckParameters (parameters); + if (parameters.Kind == ModuleKind.NetModule) + throw new ArgumentException ("kind"); + + var assembly = ModuleDefinition.CreateModule (moduleName, parameters).Assembly; + assembly.Name = assemblyName; + + return assembly; + } +#endif + + public static AssemblyDefinition ReadAssembly (string fileName) + { + return ReadAssembly (ModuleDefinition.ReadModule (fileName)); + } + + public static AssemblyDefinition ReadAssembly (string fileName, ReaderParameters parameters) + { + return ReadAssembly (ModuleDefinition.ReadModule (fileName, parameters)); + } + + public static AssemblyDefinition ReadAssembly (Stream stream) + { + return ReadAssembly (ModuleDefinition.ReadModule (stream)); + } + + public static AssemblyDefinition ReadAssembly (Stream stream, ReaderParameters parameters) + { + return ReadAssembly (ModuleDefinition.ReadModule (stream, parameters)); + } + + static AssemblyDefinition ReadAssembly (ModuleDefinition module) + { + var assembly = module.Assembly; + if (assembly == null) + throw new ArgumentException (); + + return assembly; + } + +#if !READ_ONLY + + public void Write (string fileName) + { + Write (fileName, new WriterParameters ()); + } + + public void Write (string fileName, WriterParameters parameters) + { + main_module.Write (fileName, parameters); + } + + public void Write () + { + main_module.Write (); + } + + public void Write (WriterParameters parameters) + { + main_module.Write (parameters); + } + + public void Write (Stream stream) + { + Write (stream, new WriterParameters ()); + } + + public void Write (Stream stream, WriterParameters parameters) + { + main_module.Write (stream, parameters); + } +#endif + + public override string ToString () + { + return this.FullName; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/AssemblyFlags.cs b/Mono.Cecil.20/Mono.Cecil/AssemblyFlags.cs new file mode 100644 index 00000000..6ca5bc27 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/AssemblyFlags.cs @@ -0,0 +1,24 @@ +// +// 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; + +namespace Mono.Cecil { + + [Flags] + public enum AssemblyAttributes : uint { + PublicKey = 0x0001, + SideBySideCompatible = 0x0000, + Retargetable = 0x0100, + WindowsRuntime = 0x0200, + DisableJITCompileOptimizer = 0x4000, + EnableJITCompileTracking = 0x8000, + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/AssemblyHashAlgorithm.cs b/Mono.Cecil.20/Mono.Cecil/AssemblyHashAlgorithm.cs new file mode 100644 index 00000000..66ef4cbb --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/AssemblyHashAlgorithm.cs @@ -0,0 +1,18 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum AssemblyHashAlgorithm : uint { + None = 0x0000, + Reserved = 0x8003, // MD5 + SHA1 = 0x8004 + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/AssemblyLinkedResource.cs b/Mono.Cecil.20/Mono.Cecil/AssemblyLinkedResource.cs new file mode 100644 index 00000000..f4896bd2 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/AssemblyLinkedResource.cs @@ -0,0 +1,39 @@ +// +// 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; + +namespace Mono.Cecil { + + public sealed class AssemblyLinkedResource : Resource { + + AssemblyNameReference reference; + + public AssemblyNameReference Assembly { + get { return reference; } + set { reference = value; } + } + + public override ResourceType ResourceType { + get { return ResourceType.AssemblyLinked; } + } + + public AssemblyLinkedResource (string name, ManifestResourceAttributes flags) + : base (name, flags) + { + } + + public AssemblyLinkedResource (string name, ManifestResourceAttributes flags, AssemblyNameReference reference) + : base (name, flags) + { + this.reference = reference; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/AssemblyNameDefinition.cs b/Mono.Cecil.20/Mono.Cecil/AssemblyNameDefinition.cs new file mode 100644 index 00000000..2511d793 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/AssemblyNameDefinition.cs @@ -0,0 +1,32 @@ +// +// 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; + +namespace Mono.Cecil { + + public sealed class AssemblyNameDefinition : AssemblyNameReference { + + public override byte [] Hash { + get { return Empty.Array; } + } + + internal AssemblyNameDefinition () + { + this.token = new MetadataToken (TokenType.Assembly, 1); + } + + public AssemblyNameDefinition (string name, Version version) + : base (name, version) + { + this.token = new MetadataToken (TokenType.Assembly, 1); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/AssemblyNameReference.cs b/Mono.Cecil.20/Mono.Cecil/AssemblyNameReference.cs new file mode 100644 index 00000000..1d12cc16 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/AssemblyNameReference.cs @@ -0,0 +1,266 @@ +// +// 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.Globalization; +using System.Security.Cryptography; +using System.Text; + +namespace Mono.Cecil { + + public class AssemblyNameReference : IMetadataScope { + + string name; + string culture; + Version version; + uint attributes; + byte [] public_key; + byte [] public_key_token; + AssemblyHashAlgorithm hash_algorithm; + byte [] hash; + + internal MetadataToken token; + + string full_name; + + public string Name { + get { return name; } + set { + name = value; + full_name = null; + } + } + + public string Culture { + get { return culture; } + set { + culture = value; + full_name = null; + } + } + + public Version Version { + get { return version; } + set { + version = Mixin.CheckVersion (value); + full_name = null; + } + } + + public AssemblyAttributes Attributes { + get { return (AssemblyAttributes) attributes; } + set { attributes = (uint) value; } + } + + public bool HasPublicKey { + get { return attributes.GetAttributes ((uint) AssemblyAttributes.PublicKey); } + set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.PublicKey, value); } + } + + public bool IsSideBySideCompatible { + get { return attributes.GetAttributes ((uint) AssemblyAttributes.SideBySideCompatible); } + set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.SideBySideCompatible, value); } + } + + public bool IsRetargetable { + get { return attributes.GetAttributes ((uint) AssemblyAttributes.Retargetable); } + set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.Retargetable, value); } + } + + public bool IsWindowsRuntime { + get { return attributes.GetAttributes ((uint) AssemblyAttributes.WindowsRuntime); } + set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.WindowsRuntime, value); } + } + + public byte [] PublicKey { + get { return public_key ?? Empty.Array; } + set { + public_key = value; + HasPublicKey = !public_key.IsNullOrEmpty (); + public_key_token = Empty.Array; + full_name = null; + } + } + + public byte [] PublicKeyToken { + get { + if (public_key_token.IsNullOrEmpty () && !public_key.IsNullOrEmpty ()) { + var hash = HashPublicKey (); + // we need the last 8 bytes in reverse order + var local_public_key_token = new byte [8]; + Array.Copy (hash, (hash.Length - 8), local_public_key_token, 0, 8); + Array.Reverse (local_public_key_token, 0, 8); + public_key_token = local_public_key_token; // publish only once finished (required for thread-safety) + } + return public_key_token ?? Empty.Array; + } + set { + public_key_token = value; + full_name = null; + } + } + + byte [] HashPublicKey () + { + HashAlgorithm algorithm; + + switch (hash_algorithm) { + case AssemblyHashAlgorithm.Reserved: + algorithm = MD5.Create (); + break; + default: + // None default to SHA1 + algorithm = SHA1.Create (); + break; + } + + using (algorithm) + return algorithm.ComputeHash (public_key); + } + + public virtual MetadataScopeType MetadataScopeType { + get { return MetadataScopeType.AssemblyNameReference; } + } + + public string FullName { + get { + if (full_name != null) + return full_name; + + const string sep = ", "; + + var builder = new StringBuilder (); + builder.Append (name); + builder.Append (sep); + builder.Append ("Version="); + builder.Append (version.ToString (fieldCount: 4)); + builder.Append (sep); + builder.Append ("Culture="); + builder.Append (string.IsNullOrEmpty (culture) ? "neutral" : culture); + builder.Append (sep); + builder.Append ("PublicKeyToken="); + + var pk_token = PublicKeyToken; + if (!pk_token.IsNullOrEmpty () && pk_token.Length > 0) { + for (int i = 0 ; i < pk_token.Length ; i++) { + builder.Append (pk_token [i].ToString ("x2")); + } + } else + builder.Append ("null"); + + if (IsRetargetable) { + builder.Append (sep); + builder.Append ("Retargetable=Yes"); + } + + return full_name = builder.ToString (); + } + } + + public static AssemblyNameReference Parse (string fullName) + { + if (fullName == null) + throw new ArgumentNullException ("fullName"); + if (fullName.Length == 0) + throw new ArgumentException ("Name can not be empty"); + + var name = new AssemblyNameReference (); + var tokens = fullName.Split (','); + for (int i = 0; i < tokens.Length; i++) { + var token = tokens [i].Trim (); + + if (i == 0) { + name.Name = token; + continue; + } + + var parts = token.Split ('='); + if (parts.Length != 2) + throw new ArgumentException ("Malformed name"); + + switch (parts [0].ToLowerInvariant ()) { + case "version": + name.Version = new Version (parts [1]); + break; + case "culture": + name.Culture = parts [1] == "neutral" ? "" : parts [1]; + break; + case "publickeytoken": + var pk_token = parts [1]; + if (pk_token == "null") + break; + + name.PublicKeyToken = new byte [pk_token.Length / 2]; + for (int j = 0; j < name.PublicKeyToken.Length; j++) + name.PublicKeyToken [j] = Byte.Parse (pk_token.Substring (j * 2, 2), NumberStyles.HexNumber); + + break; + } + } + + return name; + } + + public AssemblyHashAlgorithm HashAlgorithm { + get { return hash_algorithm; } + set { hash_algorithm = value; } + } + + public virtual byte [] Hash { + get { return hash; } + set { hash = value; } + } + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + internal AssemblyNameReference () + { + this.version = Mixin.ZeroVersion; + this.token = new MetadataToken (TokenType.AssemblyRef); + } + + public AssemblyNameReference (string name, Version version) + { + Mixin.CheckName (name); + + this.name = name; + this.version = Mixin.CheckVersion (version); + this.hash_algorithm = AssemblyHashAlgorithm.None; + this.token = new MetadataToken (TokenType.AssemblyRef); + } + + public override string ToString () + { + return this.FullName; + } + } + + partial class Mixin { + + public static Version ZeroVersion = new Version (0, 0, 0 ,0); + + public static Version CheckVersion (Version version) + { + if (version == null) + return ZeroVersion; + + if (version.Build == -1) + return new Version (version.Major, version.Minor, 0, 0); + + if (version.Revision == -1) + return new Version (version.Major, version.Minor, version.Build, 0); + + return version; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil.20/Mono.Cecil/AssemblyReader.cs new file mode 100644 index 00000000..752a49e6 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/AssemblyReader.cs @@ -0,0 +1,3892 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Text; + +using Mono.Collections.Generic; +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; + +using RVA = System.UInt32; + +namespace Mono.Cecil { + + abstract class ModuleReader { + + readonly protected ModuleDefinition module; + + protected ModuleReader (Image image, ReadingMode mode) + { + this.module = new ModuleDefinition (image); + this.module.ReadingMode = mode; + } + + protected abstract void ReadModule (); + public abstract void ReadSymbols (ModuleDefinition module); + + protected void ReadModuleManifest (MetadataReader reader) + { + reader.Populate (module); + + ReadAssembly (reader); + } + + void ReadAssembly (MetadataReader reader) + { + var name = reader.ReadAssemblyNameDefinition (); + if (name == null) { + module.kind = ModuleKind.NetModule; + return; + } + + var assembly = new AssemblyDefinition (); + assembly.Name = name; + + module.assembly = assembly; + assembly.main_module = module; + } + + public static ModuleDefinition CreateModule (Image image, ReaderParameters parameters) + { + var reader = CreateModuleReader (image, parameters.ReadingMode); + var module = reader.module; + + if (parameters.assembly_resolver != null) + module.assembly_resolver = Disposable.NotOwned (parameters.assembly_resolver); + + if (parameters.metadata_resolver != null) + module.metadata_resolver = parameters.metadata_resolver; + +#if !READ_ONLY + if (parameters.metadata_importer_provider != null) + module.metadata_importer = parameters.metadata_importer_provider.GetMetadataImporter (module); + if (parameters.reflection_importer_provider != null) + module.reflection_importer = parameters.reflection_importer_provider.GetReflectionImporter (module); +#endif + + GetMetadataKind (module, parameters); + + reader.ReadModule (); + + ReadSymbols (module, parameters); + + reader.ReadSymbols (module); + + if (parameters.ReadingMode == ReadingMode.Immediate) + module.MetadataSystem.Clear (); + + return module; + } + + static void ReadSymbols (ModuleDefinition module, ReaderParameters parameters) + { + var symbol_reader_provider = parameters.SymbolReaderProvider; + + if (symbol_reader_provider == null && parameters.ReadSymbols) + symbol_reader_provider = new DefaultSymbolReaderProvider (); + + if (symbol_reader_provider != null) { + module.SymbolReaderProvider = symbol_reader_provider; + + var reader = parameters.SymbolStream != null + ? symbol_reader_provider.GetSymbolReader (module, parameters.SymbolStream) + : symbol_reader_provider.GetSymbolReader (module, module.FileName); + + if (reader != null) + module.ReadSymbols (reader); + } + + if (module.Image.HasDebugTables ()) + module.ReadSymbols (new PortablePdbReader (module.Image, module)); + } + + static void GetMetadataKind (ModuleDefinition module, ReaderParameters parameters) + { + if (!parameters.ApplyWindowsRuntimeProjections) { + module.MetadataKind = MetadataKind.Ecma335; + return; + } + + var runtime_version = module.RuntimeVersion; + + if (!runtime_version.Contains ("WindowsRuntime")) + module.MetadataKind = MetadataKind.Ecma335; + else if (runtime_version.Contains ("CLR")) + module.MetadataKind = MetadataKind.ManagedWindowsMetadata; + else + module.MetadataKind = MetadataKind.WindowsMetadata; + } + + static ModuleReader CreateModuleReader (Image image, ReadingMode mode) + { + switch (mode) { + case ReadingMode.Immediate: + return new ImmediateModuleReader (image); + case ReadingMode.Deferred: + return new DeferredModuleReader (image); + default: + throw new ArgumentException (); + } + } + } + + sealed class ImmediateModuleReader : ModuleReader { + + bool resolve_attributes; + + public ImmediateModuleReader (Image image) + : base (image, ReadingMode.Immediate) + { + } + + protected override void ReadModule () + { + this.module.Read (this.module, (module, reader) => { + ReadModuleManifest (reader); + ReadModule (module, resolve_attributes: true); + return module; + }); + } + + public void ReadModule (ModuleDefinition module, bool resolve_attributes) + { + this.resolve_attributes = resolve_attributes; + + if (module.HasAssemblyReferences) + Mixin.Read (module.AssemblyReferences); + if (module.HasResources) + Mixin.Read (module.Resources); + if (module.HasModuleReferences) + Mixin.Read (module.ModuleReferences); + if (module.HasTypes) + ReadTypes (module.Types); + if (module.HasExportedTypes) + Mixin.Read (module.ExportedTypes); + + ReadCustomAttributes (module); + + var assembly = module.Assembly; + if (assembly == null) + return; + + ReadCustomAttributes (assembly); + ReadSecurityDeclarations (assembly); + } + + void ReadTypes (Collection types) + { + for (int i = 0; i < types.Count; i++) + ReadType (types [i]); + } + + void ReadType (TypeDefinition type) + { + ReadGenericParameters (type); + + if (type.HasInterfaces) + ReadInterfaces (type); + + if (type.HasNestedTypes) + ReadTypes (type.NestedTypes); + + if (type.HasLayoutInfo) + Mixin.Read (type.ClassSize); + + if (type.HasFields) + ReadFields (type); + + if (type.HasMethods) + ReadMethods (type); + + if (type.HasProperties) + ReadProperties (type); + + if (type.HasEvents) + ReadEvents (type); + + ReadSecurityDeclarations (type); + ReadCustomAttributes (type); + } + + void ReadInterfaces (TypeDefinition type) + { + var interfaces = type.Interfaces; + + for (int i = 0; i < interfaces.Count; i++) + ReadCustomAttributes (interfaces [i]); + } + + void ReadGenericParameters (IGenericParameterProvider provider) + { + if (!provider.HasGenericParameters) + return; + + var parameters = provider.GenericParameters; + + for (int i = 0; i < parameters.Count; i++) { + var parameter = parameters [i]; + + if (parameter.HasConstraints) + Mixin.Read (parameter.Constraints); + + ReadCustomAttributes (parameter); + } + } + + void ReadSecurityDeclarations (ISecurityDeclarationProvider provider) + { + if (!provider.HasSecurityDeclarations) + return; + + var security_declarations = provider.SecurityDeclarations; + + if (!resolve_attributes) + return; + + for (int i = 0; i < security_declarations.Count; i++) { + var security_declaration = security_declarations [i]; + + Mixin.Read (security_declaration.SecurityAttributes); + } + } + + void ReadCustomAttributes (ICustomAttributeProvider provider) + { + if (!provider.HasCustomAttributes) + return; + + var custom_attributes = provider.CustomAttributes; + + if (!resolve_attributes) + return; + + for (int i = 0; i < custom_attributes.Count; i++) { + var custom_attribute = custom_attributes [i]; + + Mixin.Read (custom_attribute.ConstructorArguments); + } + } + + void ReadFields (TypeDefinition type) + { + var fields = type.Fields; + + for (int i = 0; i < fields.Count; i++) { + var field = fields [i]; + + if (field.HasConstant) + Mixin.Read (field.Constant); + + if (field.HasLayoutInfo) + Mixin.Read (field.Offset); + + if (field.RVA > 0) + Mixin.Read (field.InitialValue); + + if (field.HasMarshalInfo) + Mixin.Read (field.MarshalInfo); + + ReadCustomAttributes (field); + } + } + + void ReadMethods (TypeDefinition type) + { + var methods = type.Methods; + + for (int i = 0; i < methods.Count; i++) { + var method = methods [i]; + + ReadGenericParameters (method); + + if (method.HasParameters) + ReadParameters (method); + + if (method.HasOverrides) + Mixin.Read (method.Overrides); + + if (method.IsPInvokeImpl) + Mixin.Read (method.PInvokeInfo); + + ReadSecurityDeclarations (method); + ReadCustomAttributes (method); + + var return_type = method.MethodReturnType; + if (return_type.HasConstant) + Mixin.Read (return_type.Constant); + + if (return_type.HasMarshalInfo) + Mixin.Read (return_type.MarshalInfo); + + ReadCustomAttributes (return_type); + } + } + + void ReadParameters (MethodDefinition method) + { + var parameters = method.Parameters; + + for (int i = 0; i < parameters.Count; i++) { + var parameter = parameters [i]; + + if (parameter.HasConstant) + Mixin.Read (parameter.Constant); + + if (parameter.HasMarshalInfo) + Mixin.Read (parameter.MarshalInfo); + + ReadCustomAttributes (parameter); + } + } + + void ReadProperties (TypeDefinition type) + { + var properties = type.Properties; + + for (int i = 0; i < properties.Count; i++) { + var property = properties [i]; + + Mixin.Read (property.GetMethod); + + if (property.HasConstant) + Mixin.Read (property.Constant); + + ReadCustomAttributes (property); + } + } + + void ReadEvents (TypeDefinition type) + { + var events = type.Events; + + for (int i = 0; i < events.Count; i++) { + var @event = events [i]; + + Mixin.Read (@event.AddMethod); + + ReadCustomAttributes (@event); + } + } + + 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.token.RID != 0 && method.debug_info == null) + method.debug_info = symbol_reader.Read (method); + } + } + } + + sealed class DeferredModuleReader : ModuleReader { + + public DeferredModuleReader (Image image) + : base (image, ReadingMode.Deferred) + { + } + + protected override void ReadModule () + { + this.module.Read (this.module, (module, reader) => { + ReadModuleManifest (reader); + return module; + }); + } + + public override void ReadSymbols (ModuleDefinition module) + { + } + } + + sealed class MetadataReader : ByteBuffer { + + readonly internal Image image; + readonly internal ModuleDefinition module; + readonly internal MetadataSystem metadata; + + internal CodeReader code; + internal IGenericContext context; + + readonly MetadataReader metadata_reader; + + public MetadataReader (ModuleDefinition module) + : base (module.Image.TableHeap.data) + { + this.image = module.Image; + this.module = module; + this.metadata = module.MetadataSystem; + this.code = new CodeReader (this); + } + + public MetadataReader (Image image, ModuleDefinition module, MetadataReader metadata_reader) + : base (image.TableHeap.data) + { + this.image = image; + this.module = module; + this.metadata = module.MetadataSystem; + this.metadata_reader = metadata_reader; + } + + int GetCodedIndexSize (CodedIndex index) + { + return image.GetCodedIndexSize (index); + } + + uint ReadByIndexSize (int size) + { + if (size == 4) + return ReadUInt32 (); + else + return ReadUInt16 (); + } + + byte [] ReadBlob () + { + var blob_heap = image.BlobHeap; + if (blob_heap == null) { + position += 2; + return Empty.Array; + } + + return blob_heap.Read (ReadBlobIndex ()); + } + + byte [] ReadBlob (uint signature) + { + var blob_heap = image.BlobHeap; + if (blob_heap == null) + return Empty.Array; + + return blob_heap.Read (signature); + } + + uint ReadBlobIndex () + { + var blob_heap = image.BlobHeap; + 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)); + } + + 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)); + } + + MetadataToken ReadMetadataToken (CodedIndex index) + { + return index.GetMetadataToken (ReadByIndexSize (GetCodedIndexSize (index))); + } + + int MoveTo (Table table) + { + var info = image.TableHeap [table]; + if (info.Length != 0) + this.position = (int) info.Offset; + + return (int) info.Length; + } + + bool MoveTo (Table table, uint row) + { + var info = image.TableHeap [table]; + var length = info.Length; + if (length == 0 || row > length) + return false; + + this.position = (int) (info.Offset + (info.RowSize * (row - 1))); + return true; + } + + public AssemblyNameDefinition ReadAssemblyNameDefinition () + { + if (MoveTo (Table.Assembly) == 0) + return null; + + var name = new AssemblyNameDefinition (); + + name.HashAlgorithm = (AssemblyHashAlgorithm) ReadUInt32 (); + + PopulateVersionAndFlags (name); + + name.PublicKey = ReadBlob (); + + PopulateNameAndCulture (name); + + return name; + } + + public ModuleDefinition Populate (ModuleDefinition module) + { + if (MoveTo (Table.Module) == 0) + return module; + + Advance (2); // Generation + + module.Name = ReadString (); + module.Mvid = ReadGuid (); + + return module; + } + + void InitializeAssemblyReferences () + { + if (metadata.AssemblyReferences != null) + return; + + int length = MoveTo (Table.AssemblyRef); + var references = metadata.AssemblyReferences = new AssemblyNameReference [length]; + + for (uint i = 0; i < length; i++) { + var reference = new AssemblyNameReference (); + reference.token = new MetadataToken (TokenType.AssemblyRef, i + 1); + + PopulateVersionAndFlags (reference); + + var key_or_token = ReadBlob (); + + if (reference.HasPublicKey) + reference.PublicKey = key_or_token; + else + reference.PublicKeyToken = key_or_token; + + PopulateNameAndCulture (reference); + + reference.Hash = ReadBlob (); + + references [i] = reference; + } + } + + public Collection ReadAssemblyReferences () + { + InitializeAssemblyReferences (); + + var references = new Collection (metadata.AssemblyReferences); + if (module.IsWindowsMetadata ()) + module.Projections.AddVirtualReferences (references); + + return references; + } + + public MethodDefinition ReadEntryPoint () + { + if (module.Image.EntryPointToken == 0) + return null; + + var token = new MetadataToken (module.Image.EntryPointToken); + return GetMethodDefinition (token.RID); + } + + public Collection ReadModules () + { + var modules = new Collection (1); + modules.Add (this.module); + + int length = MoveTo (Table.File); + for (uint i = 1; i <= length; i++) { + var attributes = (FileAttributes) ReadUInt32 (); + var name = ReadString (); + ReadBlobIndex (); + + if (attributes != FileAttributes.ContainsMetaData) + continue; + + var parameters = new ReaderParameters { + ReadingMode = module.ReadingMode, + SymbolReaderProvider = module.SymbolReaderProvider, + AssemblyResolver = module.AssemblyResolver + }; + + modules.Add (ModuleDefinition.ReadModule ( + GetModuleFileName (name), parameters)); + } + + return modules; + } + + string GetModuleFileName (string name) + { + if (module.FileName == null) + throw new NotSupportedException (); + + var path = Path.GetDirectoryName (module.FileName); + return Path.Combine (path, name); + } + + void InitializeModuleReferences () + { + if (metadata.ModuleReferences != null) + return; + + int length = MoveTo (Table.ModuleRef); + var references = metadata.ModuleReferences = new ModuleReference [length]; + + for (uint i = 0; i < length; i++) { + var reference = new ModuleReference (ReadString ()); + reference.token = new MetadataToken (TokenType.ModuleRef, i + 1); + + references [i] = reference; + } + } + + public Collection ReadModuleReferences () + { + InitializeModuleReferences (); + + return new Collection (metadata.ModuleReferences); + } + + public bool HasFileResource () + { + int length = MoveTo (Table.File); + if (length == 0) + return false; + + for (uint i = 1; i <= length; i++) + if (ReadFileRecord (i).Col1 == FileAttributes.ContainsNoMetaData) + return true; + + return false; + } + + public Collection ReadResources () + { + int length = MoveTo (Table.ManifestResource); + var resources = new Collection (length); + + for (int i = 1; i <= length; i++) { + var offset = ReadUInt32 (); + var flags = (ManifestResourceAttributes) ReadUInt32 (); + var name = ReadString (); + var implementation = ReadMetadataToken (CodedIndex.Implementation); + + Resource resource; + + if (implementation.RID == 0) { + resource = new EmbeddedResource (name, flags, offset, this); + } else if (implementation.TokenType == TokenType.AssemblyRef) { + resource = new AssemblyLinkedResource (name, flags) { + Assembly = (AssemblyNameReference) GetTypeReferenceScope (implementation), + }; + } else if (implementation.TokenType == TokenType.File) { + var file_record = ReadFileRecord (implementation.RID); + + resource = new LinkedResource (name, flags) { + File = file_record.Col2, + hash = ReadBlob (file_record.Col3) + }; + } else + continue; + + resources.Add (resource); + } + + return resources; + } + + Row ReadFileRecord (uint rid) + { + var position = this.position; + + if (!MoveTo (Table.File, rid)) + throw new ArgumentException (); + + var record = new Row ( + (FileAttributes) ReadUInt32 (), + ReadString (), + ReadBlobIndex ()); + + this.position = position; + + return record; + } + + public byte [] GetManagedResource (uint offset) + { + return image.GetReaderAt (image.Resources.VirtualAddress, offset, (o, reader) => { + reader.Advance ((int) o); + return reader.ReadBytes (reader.ReadInt32 ()); + }) ?? Empty.Array; + } + + void PopulateVersionAndFlags (AssemblyNameReference name) + { + name.Version = new Version ( + ReadUInt16 (), + ReadUInt16 (), + ReadUInt16 (), + ReadUInt16 ()); + + name.Attributes = (AssemblyAttributes) ReadUInt32 (); + } + + void PopulateNameAndCulture (AssemblyNameReference name) + { + name.Name = ReadString (); + name.Culture = ReadString (); + } + + public TypeDefinitionCollection ReadTypes () + { + InitializeTypeDefinitions (); + var mtypes = metadata.Types; + var type_count = mtypes.Length - metadata.NestedTypes.Count; + var types = new TypeDefinitionCollection (module, type_count); + + for (int i = 0; i < mtypes.Length; i++) { + var type = mtypes [i]; + if (IsNested (type.Attributes)) + continue; + + types.Add (type); + } + + if (image.HasTable (Table.MethodPtr) || image.HasTable (Table.FieldPtr)) + CompleteTypes (); + + return types; + } + + void CompleteTypes () + { + var types = metadata.Types; + + for (int i = 0; i < types.Length; i++) { + var type = types [i]; + + Mixin.Read (type.Fields); + Mixin.Read (type.Methods); + } + } + + void InitializeTypeDefinitions () + { + if (metadata.Types != null) + return; + + InitializeNestedTypes (); + InitializeFields (); + InitializeMethods (); + + int length = MoveTo (Table.TypeDef); + var types = metadata.Types = new TypeDefinition [length]; + + for (uint i = 0; i < length; i++) { + if (types [i] != null) + continue; + + types [i] = ReadType (i + 1); + } + } + + static bool IsNested (TypeAttributes attributes) + { + switch (attributes & TypeAttributes.VisibilityMask) { + case TypeAttributes.NestedAssembly: + case TypeAttributes.NestedFamANDAssem: + case TypeAttributes.NestedFamily: + case TypeAttributes.NestedFamORAssem: + case TypeAttributes.NestedPrivate: + case TypeAttributes.NestedPublic: + return true; + default: + return false; + } + } + + public bool HasNestedTypes (TypeDefinition type) + { + Collection mapping; + InitializeNestedTypes (); + + if (!metadata.TryGetNestedTypeMapping (type, out mapping)) + return false; + + return mapping.Count > 0; + } + + public Collection ReadNestedTypes (TypeDefinition type) + { + InitializeNestedTypes (); + Collection mapping; + if (!metadata.TryGetNestedTypeMapping (type, out mapping)) + return new MemberDefinitionCollection (type); + + var nested_types = new MemberDefinitionCollection (type, mapping.Count); + + for (int i = 0; i < mapping.Count; i++) { + var nested_type = GetTypeDefinition (mapping [i]); + + if (nested_type != null) + nested_types.Add (nested_type); + } + + metadata.RemoveNestedTypeMapping (type); + + return nested_types; + } + + void InitializeNestedTypes () + { + if (metadata.NestedTypes != null) + return; + + var length = MoveTo (Table.NestedClass); + + metadata.NestedTypes = new Dictionary> (length); + metadata.ReverseNestedTypes = new Dictionary (length); + + if (length == 0) + return; + + for (int i = 1; i <= length; i++) { + var nested = ReadTableIndex (Table.TypeDef); + var declaring = ReadTableIndex (Table.TypeDef); + + AddNestedMapping (declaring, nested); + } + } + + void AddNestedMapping (uint declaring, uint nested) + { + metadata.SetNestedTypeMapping (declaring, AddMapping (metadata.NestedTypes, declaring, nested)); + metadata.SetReverseNestedTypeMapping (nested, declaring); + } + + static Collection AddMapping (Dictionary> cache, TKey key, TValue value) + { + Collection mapped; + if (!cache.TryGetValue (key, out mapped)) { + mapped = new Collection (); + } + mapped.Add (value); + return mapped; + } + + TypeDefinition ReadType (uint rid) + { + if (!MoveTo (Table.TypeDef, rid)) + return null; + + var attributes = (TypeAttributes) ReadUInt32 (); + var name = ReadString (); + var @namespace = ReadString (); + var type = new TypeDefinition (@namespace, name, attributes); + type.token = new MetadataToken (TokenType.TypeDef, rid); + type.scope = module; + type.module = module; + + metadata.AddTypeDefinition (type); + + this.context = type; + + type.BaseType = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef)); + + type.fields_range = ReadListRange (rid, Table.TypeDef, Table.Field); + type.methods_range = ReadListRange (rid, Table.TypeDef, Table.Method); + + if (IsNested (attributes)) + type.DeclaringType = GetNestedTypeDeclaringType (type); + + if (module.IsWindowsMetadata ()) + WindowsRuntimeProjections.Project (type); + + return type; + } + + TypeDefinition GetNestedTypeDeclaringType (TypeDefinition type) + { + uint declaring_rid; + if (!metadata.TryGetReverseNestedTypeMapping (type, out declaring_rid)) + return null; + + metadata.RemoveReverseNestedTypeMapping (type); + return GetTypeDefinition (declaring_rid); + } + + Range ReadListRange (uint current_index, Table current, Table target) + { + var list = new Range (); + + var start = ReadTableIndex (target); + if (start == 0) + return list; + + uint next_index; + var current_table = image.TableHeap [current]; + + if (current_index == current_table.Length) + next_index = image.TableHeap [target].Length + 1; + else { + var position = this.position; + this.position += (int) (current_table.RowSize - image.GetTableIndexSize (target)); + next_index = ReadTableIndex (target); + this.position = position; + } + + list.Start = start; + list.Length = next_index - start; + + return list; + } + + public Row ReadTypeLayout (TypeDefinition type) + { + InitializeTypeLayouts (); + Row class_layout; + var rid = type.token.RID; + if (!metadata.ClassLayouts.TryGetValue (rid, out class_layout)) + return new Row (Mixin.NoDataMarker, Mixin.NoDataMarker); + + type.PackingSize = (short) class_layout.Col1; + type.ClassSize = (int) class_layout.Col2; + + metadata.ClassLayouts.Remove (rid); + + return new Row ((short) class_layout.Col1, (int) class_layout.Col2); + } + + void InitializeTypeLayouts () + { + if (metadata.ClassLayouts != null) + return; + + int length = MoveTo (Table.ClassLayout); + + var class_layouts = metadata.ClassLayouts = new Dictionary> (length); + + for (uint i = 0; i < length; i++) { + var packing_size = ReadUInt16 (); + var class_size = ReadUInt32 (); + + var parent = ReadTableIndex (Table.TypeDef); + + class_layouts.Add (parent, new Row (packing_size, class_size)); + } + } + + public TypeReference GetTypeDefOrRef (MetadataToken token) + { + return (TypeReference) LookupToken (token); + } + + public TypeDefinition GetTypeDefinition (uint rid) + { + InitializeTypeDefinitions (); + + var type = metadata.GetTypeDefinition (rid); + if (type != null) + return type; + + return ReadTypeDefinition (rid); + } + + TypeDefinition ReadTypeDefinition (uint rid) + { + if (!MoveTo (Table.TypeDef, rid)) + return null; + + return ReadType (rid); + } + + void InitializeTypeReferences () + { + if (metadata.TypeReferences != null) + return; + + metadata.TypeReferences = new TypeReference [image.GetTableLength (Table.TypeRef)]; + } + + public TypeReference GetTypeReference (string scope, string full_name) + { + InitializeTypeReferences (); + + var length = metadata.TypeReferences.Length; + + for (uint i = 1; i <= length; i++) { + var type = GetTypeReference (i); + + if (type.FullName != full_name) + continue; + + if (string.IsNullOrEmpty (scope)) + return type; + + if (type.Scope.Name == scope) + return type; + } + + return null; + } + + TypeReference GetTypeReference (uint rid) + { + InitializeTypeReferences (); + + var type = metadata.GetTypeReference (rid); + if (type != null) + return type; + + return ReadTypeReference (rid); + } + + TypeReference ReadTypeReference (uint rid) + { + if (!MoveTo (Table.TypeRef, rid)) + return null; + + TypeReference declaring_type = null; + IMetadataScope scope; + + var scope_token = ReadMetadataToken (CodedIndex.ResolutionScope); + + var name = ReadString (); + var @namespace = ReadString (); + + var type = new TypeReference ( + @namespace, + name, + module, + null); + + type.token = new MetadataToken (TokenType.TypeRef, rid); + + metadata.AddTypeReference (type); + + if (scope_token.TokenType == TokenType.TypeRef) { + declaring_type = GetTypeDefOrRef (scope_token); + + scope = declaring_type != null + ? declaring_type.Scope + : module; + } else + scope = GetTypeReferenceScope (scope_token); + + type.scope = scope; + type.DeclaringType = declaring_type; + + MetadataSystem.TryProcessPrimitiveTypeReference (type); + + if (type.Module.IsWindowsMetadata ()) + WindowsRuntimeProjections.Project (type); + + return type; + } + + IMetadataScope GetTypeReferenceScope (MetadataToken scope) + { + if (scope.TokenType == TokenType.Module) + return module; + + IMetadataScope[] scopes; + + switch (scope.TokenType) { + case TokenType.AssemblyRef: + InitializeAssemblyReferences (); + scopes = metadata.AssemblyReferences; + break; + case TokenType.ModuleRef: + InitializeModuleReferences (); + scopes = metadata.ModuleReferences; + break; + default: + throw new NotSupportedException (); + } + + var index = scope.RID - 1; + if (index < 0 || index >= scopes.Length) + return null; + + return scopes [index]; + } + + public IEnumerable GetTypeReferences () + { + InitializeTypeReferences (); + + var length = image.GetTableLength (Table.TypeRef); + + var type_references = new TypeReference [length]; + + for (uint i = 1; i <= length; i++) + type_references [i - 1] = GetTypeReference (i); + + return type_references; + } + + TypeReference GetTypeSpecification (uint rid) + { + if (!MoveTo (Table.TypeSpec, rid)) + return null; + + var reader = ReadSignature (ReadBlobIndex ()); + var type = reader.ReadTypeSignature (); + if (type.token.RID == 0) + type.token = new MetadataToken (TokenType.TypeSpec, rid); + + return type; + } + + SignatureReader ReadSignature (uint signature) + { + return new SignatureReader (signature, this); + } + + public bool HasInterfaces (TypeDefinition type) + { + InitializeInterfaces (); + Collection> mapping; + + return metadata.TryGetInterfaceMapping (type, out mapping); + } + + public InterfaceImplementationCollection ReadInterfaces (TypeDefinition type) + { + InitializeInterfaces (); + Collection> mapping; + + if (!metadata.TryGetInterfaceMapping (type, out mapping)) + return new InterfaceImplementationCollection (type); + + var interfaces = new InterfaceImplementationCollection (type, mapping.Count); + + this.context = type; + + for (int i = 0; i < mapping.Count; i++) { + interfaces.Add ( + new InterfaceImplementation ( + GetTypeDefOrRef (mapping [i].Col2), + new MetadataToken(TokenType.InterfaceImpl, mapping [i].Col1))); + } + + metadata.RemoveInterfaceMapping (type); + + return interfaces; + } + + void InitializeInterfaces () + { + if (metadata.Interfaces != null) + return; + + int length = MoveTo (Table.InterfaceImpl); + + metadata.Interfaces = new Dictionary>> (length); + + for (uint i = 1; i <= length; i++) { + var type = ReadTableIndex (Table.TypeDef); + var @interface = ReadMetadataToken (CodedIndex.TypeDefOrRef); + + AddInterfaceMapping (type, new Row (i, @interface)); + } + } + + void AddInterfaceMapping (uint type, Row @interface) + { + metadata.SetInterfaceMapping (type, AddMapping (metadata.Interfaces, type, @interface)); + } + + public Collection ReadFields (TypeDefinition type) + { + var fields_range = type.fields_range; + if (fields_range.Length == 0) + return new MemberDefinitionCollection (type); + + var fields = new MemberDefinitionCollection (type, (int) fields_range.Length); + this.context = type; + + if (!MoveTo (Table.FieldPtr, fields_range.Start)) { + if (!MoveTo (Table.Field, fields_range.Start)) + return fields; + + for (uint i = 0; i < fields_range.Length; i++) + ReadField (fields_range.Start + i, fields); + } else + ReadPointers (Table.FieldPtr, Table.Field, fields_range, fields, ReadField); + + return fields; + } + + void ReadField (uint field_rid, Collection fields) + { + var attributes = (FieldAttributes) ReadUInt16 (); + var name = ReadString (); + var signature = ReadBlobIndex (); + + var field = new FieldDefinition (name, attributes, ReadFieldType (signature)); + field.token = new MetadataToken (TokenType.Field, field_rid); + metadata.AddFieldDefinition (field); + + if (IsDeleted (field)) + return; + + fields.Add (field); + + if (module.IsWindowsMetadata ()) + WindowsRuntimeProjections.Project (field); + } + + void InitializeFields () + { + if (metadata.Fields != null) + return; + + metadata.Fields = new FieldDefinition [image.GetTableLength (Table.Field)]; + } + + TypeReference ReadFieldType (uint signature) + { + var reader = ReadSignature (signature); + + const byte field_sig = 0x6; + + if (reader.ReadByte () != field_sig) + throw new NotSupportedException (); + + return reader.ReadTypeSignature (); + } + + public int ReadFieldRVA (FieldDefinition field) + { + InitializeFieldRVAs (); + var rid = field.token.RID; + + RVA rva; + if (!metadata.FieldRVAs.TryGetValue (rid, out rva)) + return 0; + + var size = GetFieldTypeSize (field.FieldType); + + if (size == 0 || rva == 0) + return 0; + + metadata.FieldRVAs.Remove (rid); + + field.InitialValue = GetFieldInitializeValue (size, rva); + + return (int) rva; + } + + byte [] GetFieldInitializeValue (int size, RVA rva) + { + return image.GetReaderAt (rva, size, (s, reader) => reader.ReadBytes (s)) ?? Empty.Array; + } + + static int GetFieldTypeSize (TypeReference type) + { + int size = 0; + + switch (type.etype) { + case ElementType.Boolean: + case ElementType.U1: + case ElementType.I1: + size = 1; + break; + case ElementType.U2: + case ElementType.I2: + case ElementType.Char: + size = 2; + break; + case ElementType.U4: + case ElementType.I4: + case ElementType.R4: + size = 4; + break; + case ElementType.U8: + case ElementType.I8: + case ElementType.R8: + size = 8; + break; + case ElementType.Ptr: + case ElementType.FnPtr: + size = IntPtr.Size; + break; + case ElementType.CModOpt: + case ElementType.CModReqD: + return GetFieldTypeSize (((IModifierType) type).ElementType); + default: + var field_type = type.Resolve (); + if (field_type != null && field_type.HasLayoutInfo) + size = field_type.ClassSize; + + break; + } + + return size; + } + + void InitializeFieldRVAs () + { + if (metadata.FieldRVAs != null) + return; + + int length = MoveTo (Table.FieldRVA); + + var field_rvas = metadata.FieldRVAs = new Dictionary (length); + + for (int i = 0; i < length; i++) { + var rva = ReadUInt32 (); + var field = ReadTableIndex (Table.Field); + + field_rvas.Add (field, rva); + } + } + + public int ReadFieldLayout (FieldDefinition field) + { + InitializeFieldLayouts (); + var rid = field.token.RID; + uint offset; + if (!metadata.FieldLayouts.TryGetValue (rid, out offset)) + return Mixin.NoDataMarker; + + metadata.FieldLayouts.Remove (rid); + + return (int) offset; + } + + void InitializeFieldLayouts () + { + if (metadata.FieldLayouts != null) + return; + + int length = MoveTo (Table.FieldLayout); + + var field_layouts = metadata.FieldLayouts = new Dictionary (length); + + for (int i = 0; i < length; i++) { + var offset = ReadUInt32 (); + var field = ReadTableIndex (Table.Field); + + field_layouts.Add (field, offset); + } + } + + public bool HasEvents (TypeDefinition type) + { + InitializeEvents (); + + Range range; + if (!metadata.TryGetEventsRange (type, out range)) + return false; + + return range.Length > 0; + } + + public Collection ReadEvents (TypeDefinition type) + { + InitializeEvents (); + Range range; + + if (!metadata.TryGetEventsRange (type, out range)) + return new MemberDefinitionCollection (type); + + var events = new MemberDefinitionCollection (type, (int) range.Length); + + metadata.RemoveEventsRange (type); + + if (range.Length == 0) + return events; + + this.context = type; + + if (!MoveTo (Table.EventPtr, range.Start)) { + if (!MoveTo (Table.Event, range.Start)) + return events; + + for (uint i = 0; i < range.Length; i++) + ReadEvent (range.Start + i, events); + } else + ReadPointers (Table.EventPtr, Table.Event, range, events, ReadEvent); + + return events; + } + + void ReadEvent (uint event_rid, Collection events) + { + var attributes = (EventAttributes) ReadUInt16 (); + var name = ReadString (); + var event_type = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef)); + + var @event = new EventDefinition (name, attributes, event_type); + @event.token = new MetadataToken (TokenType.Event, event_rid); + + if (IsDeleted (@event)) + return; + + events.Add (@event); + } + + void InitializeEvents () + { + if (metadata.Events != null) + return; + + int length = MoveTo (Table.EventMap); + + metadata.Events = new Dictionary (length); + + for (uint i = 1; i <= length; i++) { + var type_rid = ReadTableIndex (Table.TypeDef); + Range events_range = ReadListRange (i, Table.EventMap, Table.Event); + metadata.AddEventsRange (type_rid, events_range); + } + } + + public bool HasProperties (TypeDefinition type) + { + InitializeProperties (); + + Range range; + if (!metadata.TryGetPropertiesRange (type, out range)) + return false; + + return range.Length > 0; + } + + public Collection ReadProperties (TypeDefinition type) + { + InitializeProperties (); + + Range range; + + if (!metadata.TryGetPropertiesRange (type, out range)) + return new MemberDefinitionCollection (type); + + metadata.RemovePropertiesRange (type); + + var properties = new MemberDefinitionCollection (type, (int) range.Length); + + if (range.Length == 0) + return properties; + + this.context = type; + + if (!MoveTo (Table.PropertyPtr, range.Start)) { + if (!MoveTo (Table.Property, range.Start)) + return properties; + for (uint i = 0; i < range.Length; i++) + ReadProperty (range.Start + i, properties); + } else + ReadPointers (Table.PropertyPtr, Table.Property, range, properties, ReadProperty); + + return properties; + } + + void ReadProperty (uint property_rid, Collection properties) + { + var attributes = (PropertyAttributes) ReadUInt16 (); + var name = ReadString (); + var signature = ReadBlobIndex (); + + var reader = ReadSignature (signature); + const byte property_signature = 0x8; + + var calling_convention = reader.ReadByte (); + + if ((calling_convention & property_signature) == 0) + throw new NotSupportedException (); + + var has_this = (calling_convention & 0x20) != 0; + + reader.ReadCompressedUInt32 (); // count + + var property = new PropertyDefinition (name, attributes, reader.ReadTypeSignature ()); + property.HasThis = has_this; + property.token = new MetadataToken (TokenType.Property, property_rid); + + if (IsDeleted (property)) + return; + + properties.Add (property); + } + + void InitializeProperties () + { + if (metadata.Properties != null) + return; + + int length = MoveTo (Table.PropertyMap); + + metadata.Properties = new Dictionary (length); + + for (uint i = 1; i <= length; i++) { + var type_rid = ReadTableIndex (Table.TypeDef); + var properties_range = ReadListRange (i, Table.PropertyMap, Table.Property); + metadata.AddPropertiesRange (type_rid, properties_range); + } + } + + MethodSemanticsAttributes ReadMethodSemantics (MethodDefinition method) + { + InitializeMethodSemantics (); + Row row; + if (!metadata.Semantics.TryGetValue (method.token.RID, out row)) + return MethodSemanticsAttributes.None; + + var type = method.DeclaringType; + + switch (row.Col1) { + case MethodSemanticsAttributes.AddOn: + GetEvent (type, row.Col2).add_method = method; + break; + case MethodSemanticsAttributes.Fire: + GetEvent (type, row.Col2).invoke_method = method; + break; + case MethodSemanticsAttributes.RemoveOn: + GetEvent (type, row.Col2).remove_method = method; + break; + case MethodSemanticsAttributes.Getter: + GetProperty (type, row.Col2).get_method = method; + break; + case MethodSemanticsAttributes.Setter: + GetProperty (type, row.Col2).set_method = method; + break; + case MethodSemanticsAttributes.Other: + switch (row.Col2.TokenType) { + case TokenType.Event: { + var @event = GetEvent (type, row.Col2); + if (@event.other_methods == null) + @event.other_methods = new Collection (); + + @event.other_methods.Add (method); + break; + } + case TokenType.Property: { + var property = GetProperty (type, row.Col2); + if (property.other_methods == null) + property.other_methods = new Collection (); + + property.other_methods.Add (method); + + break; + } + default: + throw new NotSupportedException (); + } + break; + default: + throw new NotSupportedException (); + } + + metadata.Semantics.Remove (method.token.RID); + + return row.Col1; + } + + static EventDefinition GetEvent (TypeDefinition type, MetadataToken token) + { + if (token.TokenType != TokenType.Event) + throw new ArgumentException (); + + return GetMember (type.Events, token); + } + + static PropertyDefinition GetProperty (TypeDefinition type, MetadataToken token) + { + if (token.TokenType != TokenType.Property) + throw new ArgumentException (); + + return GetMember (type.Properties, token); + } + + static TMember GetMember (Collection members, MetadataToken token) where TMember : IMemberDefinition + { + for (int i = 0; i < members.Count; i++) { + var member = members [i]; + if (member.MetadataToken == token) + return member; + } + + throw new ArgumentException (); + } + + void InitializeMethodSemantics () + { + if (metadata.Semantics != null) + return; + + int length = MoveTo (Table.MethodSemantics); + + var semantics = metadata.Semantics = new Dictionary> (0); + + for (uint i = 0; i < length; i++) { + var attributes = (MethodSemanticsAttributes) ReadUInt16 (); + var method_rid = ReadTableIndex (Table.Method); + var association = ReadMetadataToken (CodedIndex.HasSemantics); + + semantics [method_rid] = new Row (attributes, association); + } + } + + public PropertyDefinition ReadMethods (PropertyDefinition property) + { + ReadAllSemantics (property.DeclaringType); + return property; + } + + public EventDefinition ReadMethods (EventDefinition @event) + { + ReadAllSemantics (@event.DeclaringType); + return @event; + } + + public MethodSemanticsAttributes ReadAllSemantics (MethodDefinition method) + { + ReadAllSemantics (method.DeclaringType); + + return method.SemanticsAttributes; + } + + void ReadAllSemantics (TypeDefinition type) + { + var methods = type.Methods; + for (int i = 0; i < methods.Count; i++) { + var method = methods [i]; + if (method.sem_attrs_ready) + continue; + + method.sem_attrs = ReadMethodSemantics (method); + method.sem_attrs_ready = true; + } + } + + public Collection ReadMethods (TypeDefinition type) + { + var methods_range = type.methods_range; + if (methods_range.Length == 0) + return new MemberDefinitionCollection (type); + + var methods = new MemberDefinitionCollection (type, (int) methods_range.Length); + if (!MoveTo (Table.MethodPtr, methods_range.Start)) { + if (!MoveTo (Table.Method, methods_range.Start)) + return methods; + + for (uint i = 0; i < methods_range.Length; i++) + ReadMethod (methods_range.Start + i, methods); + } else + ReadPointers (Table.MethodPtr, Table.Method, methods_range, methods, ReadMethod); + + return methods; + } + + void ReadPointers (Table ptr, Table table, Range range, Collection members, Action> reader) + where TMember : IMemberDefinition + { + for (uint i = 0; i < range.Length; i++) { + MoveTo (ptr, range.Start + i); + + var rid = ReadTableIndex (table); + MoveTo (table, rid); + + reader (rid, members); + } + } + + static bool IsDeleted (IMemberDefinition member) + { + return member.IsSpecialName && member.Name == "_Deleted"; + } + + void InitializeMethods () + { + if (metadata.Methods != null) + return; + + metadata.Methods = new MethodDefinition [image.GetTableLength (Table.Method)]; + } + + void ReadMethod (uint method_rid, Collection methods) + { + var method = new MethodDefinition (); + method.rva = ReadUInt32 (); + method.ImplAttributes = (MethodImplAttributes) ReadUInt16 (); + method.Attributes = (MethodAttributes) ReadUInt16 (); + method.Name = ReadString (); + method.token = new MetadataToken (TokenType.Method, method_rid); + + if (IsDeleted (method)) + return; + + methods.Add (method); // attach method + + var signature = ReadBlobIndex (); + var param_range = ReadListRange (method_rid, Table.Method, Table.Param); + + this.context = method; + + ReadMethodSignature (signature, method); + metadata.AddMethodDefinition (method); + + if (param_range.Length != 0) { + var position = base.position; + ReadParameters (method, param_range); + base.position = position; + } + + if (module.IsWindowsMetadata ()) + WindowsRuntimeProjections.Project (method); + } + + void ReadParameters (MethodDefinition method, Range param_range) + { + if (!MoveTo (Table.ParamPtr, param_range.Start)) { + if (!MoveTo (Table.Param, param_range.Start)) + return; + + for (uint i = 0; i < param_range.Length; i++) + ReadParameter (param_range.Start + i, method); + } else + ReadParameterPointers (method, param_range); + } + + void ReadParameterPointers (MethodDefinition method, Range range) + { + for (uint i = 0; i < range.Length; i++) { + MoveTo (Table.ParamPtr, range.Start + i); + + var rid = ReadTableIndex (Table.Param); + + MoveTo (Table.Param, rid); + + ReadParameter (rid, method); + } + } + + void ReadParameter (uint param_rid, MethodDefinition method) + { + var attributes = (ParameterAttributes) ReadUInt16 (); + var sequence = ReadUInt16 (); + var name = ReadString (); + + var parameter = sequence == 0 + ? method.MethodReturnType.Parameter + : method.Parameters [sequence - 1]; + + parameter.token = new MetadataToken (TokenType.Param, param_rid); + parameter.Name = name; + parameter.Attributes = attributes; + } + + void ReadMethodSignature (uint signature, IMethodSignature method) + { + var reader = ReadSignature (signature); + reader.ReadMethodSignature (method); + } + + public PInvokeInfo ReadPInvokeInfo (MethodDefinition method) + { + InitializePInvokes (); + Row row; + + var rid = method.token.RID; + + if (!metadata.PInvokes.TryGetValue (rid, out row)) + return null; + + metadata.PInvokes.Remove (rid); + + return new PInvokeInfo ( + row.Col1, + image.StringHeap.Read (row.Col2), + module.ModuleReferences [(int) row.Col3 - 1]); + } + + void InitializePInvokes () + { + if (metadata.PInvokes != null) + return; + + int length = MoveTo (Table.ImplMap); + + var pinvokes = metadata.PInvokes = new Dictionary> (length); + + for (int i = 1; i <= length; i++) { + var attributes = (PInvokeAttributes) ReadUInt16 (); + var method = ReadMetadataToken (CodedIndex.MemberForwarded); + var name = ReadStringIndex (); + var scope = ReadTableIndex (Table.File); + + if (method.TokenType != TokenType.Method) + continue; + + pinvokes.Add (method.RID, new Row (attributes, name, scope)); + } + } + + public bool HasGenericParameters (IGenericParameterProvider provider) + { + InitializeGenericParameters (); + + Range [] ranges; + if (!metadata.TryGetGenericParameterRanges (provider, out ranges)) + return false; + + return RangesSize (ranges) > 0; + } + + public Collection ReadGenericParameters (IGenericParameterProvider provider) + { + InitializeGenericParameters (); + + Range [] ranges; + if (!metadata.TryGetGenericParameterRanges (provider, out ranges)) + return new GenericParameterCollection (provider); + + metadata.RemoveGenericParameterRange (provider); + + var generic_parameters = new GenericParameterCollection (provider, RangesSize (ranges)); + + for (int i = 0; i < ranges.Length; i++) + ReadGenericParametersRange (ranges [i], provider, generic_parameters); + + return generic_parameters; + } + + void ReadGenericParametersRange (Range range, IGenericParameterProvider provider, GenericParameterCollection generic_parameters) + { + if (!MoveTo (Table.GenericParam, range.Start)) + return; + + for (uint i = 0; i < range.Length; i++) { + ReadUInt16 (); // index + var flags = (GenericParameterAttributes) ReadUInt16 (); + ReadMetadataToken (CodedIndex.TypeOrMethodDef); + var name = ReadString (); + + var parameter = new GenericParameter (name, provider); + parameter.token = new MetadataToken (TokenType.GenericParam, range.Start + i); + parameter.Attributes = flags; + + generic_parameters.Add (parameter); + } + } + + void InitializeGenericParameters () + { + if (metadata.GenericParameters != null) + return; + + metadata.GenericParameters = InitializeRanges ( + Table.GenericParam, () => { + Advance (4); + var next = ReadMetadataToken (CodedIndex.TypeOrMethodDef); + ReadStringIndex (); + return next; + }); + } + + Dictionary InitializeRanges (Table table, Func get_next) + { + int length = MoveTo (table); + var ranges = new Dictionary (length); + + if (length == 0) + return ranges; + + MetadataToken owner = MetadataToken.Zero; + Range range = new Range (1, 0); + + for (uint i = 1; i <= length; i++) { + var next = get_next (); + + if (i == 1) { + owner = next; + range.Length++; + } else if (next != owner) { + AddRange (ranges, owner, range); + range = new Range (i, 1); + owner = next; + } else + range.Length++; + } + + AddRange (ranges, owner, range); + + return ranges; + } + + static void AddRange (Dictionary ranges, MetadataToken owner, Range range) + { + if (owner.RID == 0) + return; + + Range [] slots; + if (!ranges.TryGetValue (owner, out slots)) { + ranges.Add (owner, new [] { range }); + return; + } + + ranges [owner] = slots.Add(range); + } + + public bool HasGenericConstraints (GenericParameter generic_parameter) + { + InitializeGenericConstraints (); + + Collection mapping; + if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping)) + return false; + + return mapping.Count > 0; + } + + public Collection ReadGenericConstraints (GenericParameter generic_parameter) + { + InitializeGenericConstraints (); + + Collection mapping; + if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping)) + return new Collection (); + + var constraints = new Collection (mapping.Count); + + this.context = (IGenericContext) generic_parameter.Owner; + + for (int i = 0; i < mapping.Count; i++) + constraints.Add (GetTypeDefOrRef (mapping [i])); + + metadata.RemoveGenericConstraintMapping (generic_parameter); + + return constraints; + } + + void InitializeGenericConstraints () + { + if (metadata.GenericConstraints != null) + return; + + var length = MoveTo (Table.GenericParamConstraint); + + metadata.GenericConstraints = new Dictionary> (length); + + for (int i = 1; i <= length; i++) + AddGenericConstraintMapping ( + ReadTableIndex (Table.GenericParam), + ReadMetadataToken (CodedIndex.TypeDefOrRef)); + } + + void AddGenericConstraintMapping (uint generic_parameter, MetadataToken constraint) + { + metadata.SetGenericConstraintMapping ( + generic_parameter, + AddMapping (metadata.GenericConstraints, generic_parameter, constraint)); + } + + public bool HasOverrides (MethodDefinition method) + { + InitializeOverrides (); + Collection mapping; + + if (!metadata.TryGetOverrideMapping (method, out mapping)) + return false; + + return mapping.Count > 0; + } + + public Collection ReadOverrides (MethodDefinition method) + { + InitializeOverrides (); + + Collection mapping; + if (!metadata.TryGetOverrideMapping (method, out mapping)) + return new Collection (); + + var overrides = new Collection (mapping.Count); + + this.context = method; + + for (int i = 0; i < mapping.Count; i++) + overrides.Add ((MethodReference) LookupToken (mapping [i])); + + metadata.RemoveOverrideMapping (method); + + return overrides; + } + + void InitializeOverrides () + { + if (metadata.Overrides != null) + return; + + var length = MoveTo (Table.MethodImpl); + + metadata.Overrides = new Dictionary> (length); + + for (int i = 1; i <= length; i++) { + ReadTableIndex (Table.TypeDef); + + var method = ReadMetadataToken (CodedIndex.MethodDefOrRef); + if (method.TokenType != TokenType.Method) + throw new NotSupportedException (); + + var @override = ReadMetadataToken (CodedIndex.MethodDefOrRef); + + AddOverrideMapping (method.RID, @override); + } + } + + void AddOverrideMapping (uint method_rid, MetadataToken @override) + { + metadata.SetOverrideMapping ( + method_rid, + AddMapping (metadata.Overrides, method_rid, @override)); + } + + public MethodBody ReadMethodBody (MethodDefinition method) + { + return code.ReadMethodBody (method); + } + + public CallSite ReadCallSite (MetadataToken token) + { + if (!MoveTo (Table.StandAloneSig, token.RID)) + return null; + + var signature = ReadBlobIndex (); + + var call_site = new CallSite (); + + ReadMethodSignature (signature, call_site); + + call_site.MetadataToken = token; + + return call_site; + } + + public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token) + { + if (!MoveTo (Table.StandAloneSig, local_var_token.RID)) + return null; + + var reader = ReadSignature (ReadBlobIndex ()); + const byte local_sig = 0x7; + + if (reader.ReadByte () != local_sig) + throw new NotSupportedException (); + + var count = reader.ReadCompressedUInt32 (); + if (count == 0) + return null; + + var variables = new VariableDefinitionCollection ((int) count); + + for (int i = 0; i < count; i++) + variables.Add (new VariableDefinition (reader.ReadTypeSignature ())); + + return variables; + } + + public IMetadataTokenProvider LookupToken (MetadataToken token) + { + var rid = token.RID; + + if (rid == 0) + return null; + + if (metadata_reader != null) + return metadata_reader.LookupToken (token); + + IMetadataTokenProvider element; + var position = this.position; + var context = this.context; + + switch (token.TokenType) { + case TokenType.TypeDef: + element = GetTypeDefinition (rid); + break; + case TokenType.TypeRef: + element = GetTypeReference (rid); + break; + case TokenType.TypeSpec: + element = GetTypeSpecification (rid); + break; + case TokenType.Field: + element = GetFieldDefinition (rid); + break; + case TokenType.Method: + element = GetMethodDefinition (rid); + break; + case TokenType.MemberRef: + element = GetMemberReference (rid); + break; + case TokenType.MethodSpec: + element = GetMethodSpecification (rid); + break; + default: + return null; + } + + this.position = position; + this.context = context; + + return element; + } + + public FieldDefinition GetFieldDefinition (uint rid) + { + InitializeTypeDefinitions (); + + var field = metadata.GetFieldDefinition (rid); + if (field != null) + return field; + + return LookupField (rid); + } + + FieldDefinition LookupField (uint rid) + { + var type = metadata.GetFieldDeclaringType (rid); + if (type == null) + return null; + + Mixin.Read (type.Fields); + + return metadata.GetFieldDefinition (rid); + } + + public MethodDefinition GetMethodDefinition (uint rid) + { + InitializeTypeDefinitions (); + + var method = metadata.GetMethodDefinition (rid); + if (method != null) + return method; + + return LookupMethod (rid); + } + + MethodDefinition LookupMethod (uint rid) + { + var type = metadata.GetMethodDeclaringType (rid); + if (type == null) + return null; + + Mixin.Read (type.Methods); + + return metadata.GetMethodDefinition (rid); + } + + MethodSpecification GetMethodSpecification (uint rid) + { + if (!MoveTo (Table.MethodSpec, rid)) + return null; + + var element_method = (MethodReference) LookupToken ( + ReadMetadataToken (CodedIndex.MethodDefOrRef)); + var signature = ReadBlobIndex (); + + var method_spec = ReadMethodSpecSignature (signature, element_method); + method_spec.token = new MetadataToken (TokenType.MethodSpec, rid); + return method_spec; + } + + MethodSpecification ReadMethodSpecSignature (uint signature, MethodReference method) + { + var reader = ReadSignature (signature); + const byte methodspec_sig = 0x0a; + + var call_conv = reader.ReadByte (); + + if (call_conv != methodspec_sig) + throw new NotSupportedException (); + + var instance = new GenericInstanceMethod (method); + + reader.ReadGenericInstanceSignature (method, instance); + + return instance; + } + + MemberReference GetMemberReference (uint rid) + { + InitializeMemberReferences (); + + var member = metadata.GetMemberReference (rid); + if (member != null) + return member; + + member = ReadMemberReference (rid); + if (member != null && !member.ContainsGenericParameter) + metadata.AddMemberReference (member); + return member; + } + + MemberReference ReadMemberReference (uint rid) + { + if (!MoveTo (Table.MemberRef, rid)) + return null; + + var token = ReadMetadataToken (CodedIndex.MemberRefParent); + var name = ReadString (); + var signature = ReadBlobIndex (); + + MemberReference member; + + switch (token.TokenType) { + case TokenType.TypeDef: + case TokenType.TypeRef: + case TokenType.TypeSpec: + member = ReadTypeMemberReference (token, name, signature); + break; + case TokenType.Method: + member = ReadMethodMemberReference (token, name, signature); + break; + default: + throw new NotSupportedException (); + } + + member.token = new MetadataToken (TokenType.MemberRef, rid); + + if (module.IsWindowsMetadata ()) + WindowsRuntimeProjections.Project (member); + + return member; + } + + MemberReference ReadTypeMemberReference (MetadataToken type, string name, uint signature) + { + var declaring_type = GetTypeDefOrRef (type); + + if (!declaring_type.IsArray) + this.context = declaring_type; + + var member = ReadMemberReferenceSignature (signature, declaring_type); + member.Name = name; + + return member; + } + + MemberReference ReadMemberReferenceSignature (uint signature, TypeReference declaring_type) + { + var reader = ReadSignature (signature); + const byte field_sig = 0x6; + + if (reader.buffer [reader.position] == field_sig) { + reader.position++; + var field = new FieldReference (); + field.DeclaringType = declaring_type; + field.FieldType = reader.ReadTypeSignature (); + return field; + } else { + var method = new MethodReference (); + method.DeclaringType = declaring_type; + reader.ReadMethodSignature (method); + return method; + } + } + + MemberReference ReadMethodMemberReference (MetadataToken token, string name, uint signature) + { + var method = GetMethodDefinition (token.RID); + + this.context = method; + + var member = ReadMemberReferenceSignature (signature, method.DeclaringType); + member.Name = name; + + return member; + } + + void InitializeMemberReferences () + { + if (metadata.MemberReferences != null) + return; + + metadata.MemberReferences = new MemberReference [image.GetTableLength (Table.MemberRef)]; + } + + public IEnumerable GetMemberReferences () + { + InitializeMemberReferences (); + + var length = image.GetTableLength (Table.MemberRef); + + var type_system = module.TypeSystem; + + var context = new MethodReference (string.Empty, type_system.Void); + context.DeclaringType = new TypeReference (string.Empty, string.Empty, module, type_system.CoreLibrary); + + var member_references = new MemberReference [length]; + + for (uint i = 1; i <= length; i++) { + this.context = context; + member_references [i - 1] = GetMemberReference (i); + } + + return member_references; + } + + void InitializeConstants () + { + if (metadata.Constants != null) + return; + + var length = MoveTo (Table.Constant); + + var constants = metadata.Constants = new Dictionary> (length); + + for (uint i = 1; i <= length; i++) { + var type = (ElementType) ReadUInt16 (); + var owner = ReadMetadataToken (CodedIndex.HasConstant); + var signature = ReadBlobIndex (); + + constants.Add (owner, new Row (type, signature)); + } + } + + public TypeReference ReadConstantSignature (MetadataToken token) + { + if (token.TokenType != TokenType.Signature) + throw new NotSupportedException (); + + if (!MoveTo (Table.StandAloneSig, token.RID)) + return null; + + return ReadFieldType (ReadBlobIndex ()); + } + + public object ReadConstant (IConstantProvider owner) + { + InitializeConstants (); + + Row row; + if (!metadata.Constants.TryGetValue (owner.MetadataToken, out row)) + return Mixin.NoValue; + + metadata.Constants.Remove (owner.MetadataToken); + + 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 (signature); + default: + return ReadConstantPrimitive (etype, signature); + } + } + + string ReadConstantString (uint signature) + { + byte [] blob; + int index, count; + + GetBlobView (signature, out blob, out index, out count); + if (count == 0) + return string.Empty; + + if ((count & 1) == 1) + count--; + + return Encoding.Unicode.GetString (blob, index, count); + } + + object ReadConstantPrimitive (ElementType type, uint signature) + { + var reader = ReadSignature (signature); + return reader.ReadConstantSignature (type); + } + + internal void InitializeCustomAttributes () + { + if (metadata.CustomAttributes != null) + return; + + metadata.CustomAttributes = InitializeRanges ( + Table.CustomAttribute, () => { + var next = ReadMetadataToken (CodedIndex.HasCustomAttribute); + ReadMetadataToken (CodedIndex.CustomAttributeType); + ReadBlobIndex (); + return next; + }); + } + + public bool HasCustomAttributes (ICustomAttributeProvider owner) + { + InitializeCustomAttributes (); + + Range [] ranges; + if (!metadata.TryGetCustomAttributeRanges (owner, out ranges)) + return false; + + return RangesSize (ranges) > 0; + } + + public Collection ReadCustomAttributes (ICustomAttributeProvider owner) + { + InitializeCustomAttributes (); + + Range [] ranges; + if (!metadata.TryGetCustomAttributeRanges (owner, out ranges)) + return new Collection (); + + var custom_attributes = new Collection (RangesSize (ranges)); + + for (int i = 0; i < ranges.Length; i++) + ReadCustomAttributeRange (ranges [i], custom_attributes); + + metadata.RemoveCustomAttributeRange (owner); + + if (module.IsWindowsMetadata ()) + foreach (var custom_attribute in custom_attributes) + WindowsRuntimeProjections.Project (owner, custom_attribute); + + return custom_attributes; + } + + void ReadCustomAttributeRange (Range range, Collection custom_attributes) + { + if (!MoveTo (Table.CustomAttribute, range.Start)) + return; + + for (var i = 0; i < range.Length; i++) { + ReadMetadataToken (CodedIndex.HasCustomAttribute); + + var constructor = (MethodReference) LookupToken ( + ReadMetadataToken (CodedIndex.CustomAttributeType)); + + var signature = ReadBlobIndex (); + + custom_attributes.Add (new CustomAttribute (signature, constructor)); + } + } + + static int RangesSize (Range [] ranges) + { + uint size = 0; + for (int i = 0; i < ranges.Length; i++) + size += ranges [i].Length; + + return (int) size; + } + + public IEnumerable GetCustomAttributes () + { + InitializeTypeDefinitions (); + + var length = image.TableHeap [Table.CustomAttribute].Length; + var custom_attributes = new Collection ((int) length); + ReadCustomAttributeRange (new Range (1, length), custom_attributes); + + return custom_attributes; + } + + public byte [] ReadCustomAttributeBlob (uint signature) + { + return ReadBlob (signature); + } + + public void ReadCustomAttributeSignature (CustomAttribute attribute) + { + var reader = ReadSignature (attribute.signature); + + if (!reader.CanReadMore ()) + return; + + if (reader.ReadUInt16 () != 0x0001) + throw new InvalidOperationException (); + + var constructor = attribute.Constructor; + if (constructor.HasParameters) + reader.ReadCustomAttributeConstructorArguments (attribute, constructor.Parameters); + + if (!reader.CanReadMore ()) + return; + + var named = reader.ReadUInt16 (); + + if (named == 0) + return; + + reader.ReadCustomAttributeNamedArguments (named, ref attribute.fields, ref attribute.properties); + } + + void InitializeMarshalInfos () + { + if (metadata.FieldMarshals != null) + return; + + var length = MoveTo (Table.FieldMarshal); + + var marshals = metadata.FieldMarshals = new Dictionary (length); + + for (int i = 0; i < length; i++) { + var token = ReadMetadataToken (CodedIndex.HasFieldMarshal); + var signature = ReadBlobIndex (); + if (token.RID == 0) + continue; + + marshals.Add (token, signature); + } + } + + public bool HasMarshalInfo (IMarshalInfoProvider owner) + { + InitializeMarshalInfos (); + + return metadata.FieldMarshals.ContainsKey (owner.MetadataToken); + } + + public MarshalInfo ReadMarshalInfo (IMarshalInfoProvider owner) + { + InitializeMarshalInfos (); + + uint signature; + if (!metadata.FieldMarshals.TryGetValue (owner.MetadataToken, out signature)) + return null; + + var reader = ReadSignature (signature); + + metadata.FieldMarshals.Remove (owner.MetadataToken); + + return reader.ReadMarshalInfo (); + } + + void InitializeSecurityDeclarations () + { + if (metadata.SecurityDeclarations != null) + return; + + metadata.SecurityDeclarations = InitializeRanges ( + Table.DeclSecurity, () => { + ReadUInt16 (); + var next = ReadMetadataToken (CodedIndex.HasDeclSecurity); + ReadBlobIndex (); + return next; + }); + } + + public bool HasSecurityDeclarations (ISecurityDeclarationProvider owner) + { + InitializeSecurityDeclarations (); + + Range [] ranges; + if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges)) + return false; + + return RangesSize (ranges) > 0; + } + + public Collection ReadSecurityDeclarations (ISecurityDeclarationProvider owner) + { + InitializeSecurityDeclarations (); + + Range [] ranges; + if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges)) + return new Collection (); + + var security_declarations = new Collection (RangesSize (ranges)); + + for (int i = 0; i < ranges.Length; i++) + ReadSecurityDeclarationRange (ranges [i], security_declarations); + + metadata.RemoveSecurityDeclarationRange (owner); + + return security_declarations; + } + + void ReadSecurityDeclarationRange (Range range, Collection security_declarations) + { + if (!MoveTo (Table.DeclSecurity, range.Start)) + return; + + for (int i = 0; i < range.Length; i++) { + var action = (SecurityAction) ReadUInt16 (); + ReadMetadataToken (CodedIndex.HasDeclSecurity); + var signature = ReadBlobIndex (); + + security_declarations.Add (new SecurityDeclaration (action, signature, module)); + } + } + + public byte [] ReadSecurityDeclarationBlob (uint signature) + { + return ReadBlob (signature); + } + + public void ReadSecurityDeclarationSignature (SecurityDeclaration declaration) + { + var signature = declaration.signature; + var reader = ReadSignature (signature); + + if (reader.buffer [reader.position] != '.') { + ReadXmlSecurityDeclaration (signature, declaration); + return; + } + + reader.position++; + var count = reader.ReadCompressedUInt32 (); + var attributes = new Collection ((int) count); + + for (int i = 0; i < count; i++) + attributes.Add (reader.ReadSecurityAttribute ()); + + declaration.security_attributes = attributes; + } + + void ReadXmlSecurityDeclaration (uint signature, SecurityDeclaration declaration) + { + var attributes = new Collection (1); + + var attribute = new SecurityAttribute ( + module.TypeSystem.LookupType ("System.Security.Permissions", "PermissionSetAttribute")); + + attribute.properties = new Collection (1); + attribute.properties.Add ( + new CustomAttributeNamedArgument ( + "XML", + new CustomAttributeArgument ( + module.TypeSystem.String, + ReadUnicodeStringBlob (signature)))); + + attributes.Add (attribute); + + declaration.security_attributes = attributes; + } + + public Collection ReadExportedTypes () + { + var length = MoveTo (Table.ExportedType); + if (length == 0) + return new Collection (); + + var exported_types = new Collection (length); + + for (int i = 1; i <= length; i++) { + var attributes = (TypeAttributes) ReadUInt32 (); + var identifier = ReadUInt32 (); + var name = ReadString (); + var @namespace = ReadString (); + var implementation = ReadMetadataToken (CodedIndex.Implementation); + + ExportedType declaring_type = null; + IMetadataScope scope = null; + + switch (implementation.TokenType) { + case TokenType.AssemblyRef: + case TokenType.File: + scope = GetExportedTypeScope (implementation); + break; + case TokenType.ExportedType: + // FIXME: if the table is not properly sorted + declaring_type = exported_types [(int) implementation.RID - 1]; + break; + } + + var exported_type = new ExportedType (@namespace, name, module, scope) { + Attributes = attributes, + Identifier = (int) identifier, + DeclaringType = declaring_type, + }; + exported_type.token = new MetadataToken (TokenType.ExportedType, i); + + exported_types.Add (exported_type); + } + + return exported_types; + } + + IMetadataScope GetExportedTypeScope (MetadataToken token) + { + var position = this.position; + IMetadataScope scope; + + switch (token.TokenType) { + case TokenType.AssemblyRef: + InitializeAssemblyReferences (); + scope = metadata.GetAssemblyNameReference (token.RID); + break; + case TokenType.File: + InitializeModuleReferences (); + scope = GetModuleReferenceFromFile (token); + break; + default: + throw new NotSupportedException (); + } + + this.position = position; + return scope; + } + + ModuleReference GetModuleReferenceFromFile (MetadataToken token) + { + if (!MoveTo (Table.File, token.RID)) + return null; + + ReadUInt32 (); + var file_name = ReadString (); + var modules = module.ModuleReferences; + + ModuleReference reference; + for (int i = 0; i < modules.Count; i++) { + reference = modules [i]; + if (reference.Name == file_name) + return reference; + } + + reference = new ModuleReference (file_name); + modules.Add (reference); + return reference; + } + + 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 (0); + + var document_index = ReadTableIndex (Table.Document); + var signature = ReadBlobIndex (); + if (signature == 0) + return new Collection (0); + + var document = GetDocument (document_index); + var reader = ReadSignature (signature); + + return reader.ReadSequencePoints (document); + } + + public Document GetDocument (uint rid) + { + var document = metadata.GetDocument (rid); + if (document == null) + return null; + + document.custom_infos = GetCustomDebugInformation (document); + return 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 (); + + Collection> records; + if (!metadata.TryGetLocalScopes (method, out records)) + return null; + + var method_scope = null as ScopeDebugInformation; + + for (int i = 0; i < records.Count; 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++) { + var variable = ReadLocalVariable (record.Col2.Start + i); + if (variable != null) + scope.variables.Add (variable); + } + } + + if (record.Col3.Length > 0) { + scope.constants = new Collection ((int) record.Col3.Length); + for (uint i = 0; i < record.Col3.Length; i++) { + var constant = ReadLocalConstant (record.Col3.Start + i); + if (constant != null) + scope.constants.Add (constant); + } + } + + 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) { + var bytes = signature.ReadBytes ((int) (signature.sig_length - (signature.position - signature.start))); + value = Encoding.Unicode.GetString (bytes, 0, bytes.Length); + } else + 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 if (type.etype == ElementType.Object || type.etype == ElementType.None || type.etype == ElementType.Class) { + value = null; + } 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 if (rows [i].Col1 == EmbeddedSourceDebugInformation.KindIdentifier) { + var signature = ReadSignature (rows [i].Col2); + var format = signature.ReadInt32 (); + var length = signature.sig_length - 4; + + var info = null as CustomDebugInformation; + + if (format == 0) { + info = new EmbeddedSourceDebugInformation (signature.ReadBytes ((int) length), compress: false); + } else if (format > 0) { + var compressed_stream = new MemoryStream (signature.ReadBytes ((int) length)); + var decompressed_document = new byte [format]; // if positive, format is the decompressed length of the document + var decompressed_stream = new MemoryStream (decompressed_document); + + using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true)) + deflate_stream.CopyTo (decompressed_stream); + + info = new EmbeddedSourceDebugInformation (decompressed_document, compress: true); + } else if (format < 0) { + info = new BinaryCustomDebugInformation (rows [i].Col1, ReadBlob (rows [i].Col2)); + } + + infos.Add (info); + } else if (rows [i].Col1 == SourceLinkDebugInformation.KindIdentifier) { + infos.Add (new SourceLinkDebugInformation (Encoding.UTF8.GetString (ReadBlob (rows [i].Col2)))); + } 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 internal uint start, sig_length; + + TypeSystem TypeSystem { + get { return reader.module.TypeSystem; } + } + + public SignatureReader (uint blob, MetadataReader reader) + : base (reader.image.BlobHeap.data) + { + this.reader = reader; + this.position = (int) blob; + this.sig_length = ReadCompressedUInt32(); + this.start = (uint) this.position; + } + + MetadataToken ReadTypeTokenSignature () + { + return CodedIndex.TypeDefOrRef.GetMetadataToken (ReadCompressedUInt32 ()); + } + + GenericParameter GetGenericParameter (GenericParameterType type, uint var) + { + var context = reader.context; + int index = (int) var; + + if (context == null) + return GetUnboundGenericParameter (type, index); + + IGenericParameterProvider provider; + + switch (type) { + case GenericParameterType.Type: + provider = context.Type; + break; + case GenericParameterType.Method: + provider = context.Method; + break; + default: + throw new NotSupportedException (); + } + + if (!context.IsDefinition) + CheckGenericContext (provider, index); + + if (index >= provider.GenericParameters.Count) + return GetUnboundGenericParameter (type, index); + + return provider.GenericParameters [index]; + } + + GenericParameter GetUnboundGenericParameter (GenericParameterType type, int index) + { + return new GenericParameter (index, type, reader.module); + } + + static void CheckGenericContext (IGenericParameterProvider owner, int index) + { + var owner_parameters = owner.GenericParameters; + + for (int i = owner_parameters.Count; i <= index; i++) + owner_parameters.Add (new GenericParameter (owner)); + } + + public void ReadGenericInstanceSignature (IGenericParameterProvider provider, IGenericInstance instance) + { + var arity = ReadCompressedUInt32 (); + + if (!provider.IsDefinition) + CheckGenericContext (provider, (int) arity - 1); + + var instance_arguments = instance.GenericArguments; + + for (int i = 0; i < arity; i++) + instance_arguments.Add (ReadTypeSignature ()); + } + + ArrayType ReadArrayTypeSignature () + { + var array = new ArrayType (ReadTypeSignature ()); + + var rank = ReadCompressedUInt32 (); + + var sizes = new uint [ReadCompressedUInt32 ()]; + for (int i = 0; i < sizes.Length; i++) + sizes [i] = ReadCompressedUInt32 (); + + var low_bounds = new int [ReadCompressedUInt32 ()]; + for (int i = 0; i < low_bounds.Length; i++) + low_bounds [i] = ReadCompressedInt32 (); + + array.Dimensions.Clear (); + + for (int i = 0; i < rank; i++) { + int? lower = null, upper = null; + + if (i < low_bounds.Length) + lower = low_bounds [i]; + + if (i < sizes.Length) + upper = lower + (int) sizes [i] - 1; + + array.Dimensions.Add (new ArrayDimension (lower, upper)); + } + + return array; + } + + TypeReference GetTypeDefOrRef (MetadataToken token) + { + return reader.GetTypeDefOrRef (token); + } + + public TypeReference ReadTypeSignature () + { + return ReadTypeSignature ((ElementType) ReadByte ()); + } + + public TypeReference ReadTypeToken () + { + return GetTypeDefOrRef (ReadTypeTokenSignature ()); + } + + TypeReference ReadTypeSignature (ElementType etype) + { + switch (etype) { + case ElementType.ValueType: { + var value_type = GetTypeDefOrRef (ReadTypeTokenSignature ()); + value_type.IsValueType = true; + return value_type; + } + case ElementType.Class: + return GetTypeDefOrRef (ReadTypeTokenSignature ()); + case ElementType.Ptr: + return new PointerType (ReadTypeSignature ()); + case ElementType.FnPtr: { + var fptr = new FunctionPointerType (); + ReadMethodSignature (fptr); + return fptr; + } + case ElementType.ByRef: + return new ByReferenceType (ReadTypeSignature ()); + case ElementType.Pinned: + return new PinnedType (ReadTypeSignature ()); + case ElementType.SzArray: + return new ArrayType (ReadTypeSignature ()); + case ElementType.Array: + return ReadArrayTypeSignature (); + case ElementType.CModOpt: + return new OptionalModifierType ( + GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ()); + case ElementType.CModReqD: + return new RequiredModifierType ( + GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ()); + case ElementType.Sentinel: + return new SentinelType (ReadTypeSignature ()); + case ElementType.Var: + return GetGenericParameter (GenericParameterType.Type, ReadCompressedUInt32 ()); + case ElementType.MVar: + return GetGenericParameter (GenericParameterType.Method, ReadCompressedUInt32 ()); + case ElementType.GenericInst: { + var is_value_type = ReadByte () == (byte) ElementType.ValueType; + var element_type = GetTypeDefOrRef (ReadTypeTokenSignature ()); + var generic_instance = new GenericInstanceType (element_type); + + ReadGenericInstanceSignature (element_type, generic_instance); + + if (is_value_type) { + generic_instance.IsValueType = true; + element_type.GetElementType ().IsValueType = true; + } + + return generic_instance; + } + case ElementType.Object: return TypeSystem.Object; + case ElementType.Void: return TypeSystem.Void; + case ElementType.TypedByRef: return TypeSystem.TypedReference; + case ElementType.I: return TypeSystem.IntPtr; + case ElementType.U: return TypeSystem.UIntPtr; + default: return GetPrimitiveType (etype); + } + } + + public void ReadMethodSignature (IMethodSignature method) + { + var calling_convention = ReadByte (); + + const byte has_this = 0x20; + const byte explicit_this = 0x40; + + if ((calling_convention & has_this) != 0) { + method.HasThis = true; + calling_convention = (byte) (calling_convention & ~has_this); + } + + if ((calling_convention & explicit_this) != 0) { + method.ExplicitThis = true; + calling_convention = (byte) (calling_convention & ~explicit_this); + } + + method.CallingConvention = (MethodCallingConvention) calling_convention; + + var generic_context = method as MethodReference; + if (generic_context != null && !generic_context.DeclaringType.IsArray) + reader.context = generic_context; + + if ((calling_convention & 0x10) != 0) { + var arity = ReadCompressedUInt32 (); + + if (generic_context != null && !generic_context.IsDefinition) + CheckGenericContext (generic_context, (int) arity -1 ); + } + + var param_count = ReadCompressedUInt32 (); + + method.MethodReturnType.ReturnType = ReadTypeSignature (); + + if (param_count == 0) + return; + + Collection parameters; + + var method_ref = method as MethodReference; + if (method_ref != null) + parameters = method_ref.parameters = new ParameterDefinitionCollection (method, (int) param_count); + else + parameters = method.Parameters; + + for (int i = 0; i < param_count; i++) + parameters.Add (new ParameterDefinition (ReadTypeSignature ())); + } + + public object ReadConstantSignature (ElementType type) + { + return ReadPrimitiveValue (type); + } + + public void ReadCustomAttributeConstructorArguments (CustomAttribute attribute, Collection parameters) + { + var count = parameters.Count; + if (count == 0) + return; + + attribute.arguments = new Collection (count); + + for (int i = 0; i < count; i++) + attribute.arguments.Add ( + ReadCustomAttributeFixedArgument (parameters [i].ParameterType)); + } + + CustomAttributeArgument ReadCustomAttributeFixedArgument (TypeReference type) + { + if (type.IsArray) + return ReadCustomAttributeFixedArrayArgument ((ArrayType) type); + + return ReadCustomAttributeElement (type); + } + + public void ReadCustomAttributeNamedArguments (ushort count, ref Collection fields, ref Collection properties) + { + for (int i = 0; i < count; i++) { + if (!CanReadMore ()) + return; + ReadCustomAttributeNamedArgument (ref fields, ref properties); + } + } + + void ReadCustomAttributeNamedArgument (ref Collection fields, ref Collection properties) + { + var kind = ReadByte (); + var type = ReadCustomAttributeFieldOrPropType (); + var name = ReadUTF8String (); + + Collection container; + switch (kind) { + case 0x53: + container = GetCustomAttributeNamedArgumentCollection (ref fields); + break; + case 0x54: + container = GetCustomAttributeNamedArgumentCollection (ref properties); + break; + default: + throw new NotSupportedException (); + } + + container.Add (new CustomAttributeNamedArgument (name, ReadCustomAttributeFixedArgument (type))); + } + + static Collection GetCustomAttributeNamedArgumentCollection (ref Collection collection) + { + if (collection != null) + return collection; + + return collection = new Collection (); + } + + CustomAttributeArgument ReadCustomAttributeFixedArrayArgument (ArrayType type) + { + var length = ReadUInt32 (); + + if (length == 0xffffffff) + return new CustomAttributeArgument (type, null); + + if (length == 0) + return new CustomAttributeArgument (type, Empty.Array); + + var arguments = new CustomAttributeArgument [length]; + var element_type = type.ElementType; + + for (int i = 0; i < length; i++) + arguments [i] = ReadCustomAttributeElement (element_type); + + return new CustomAttributeArgument (type, arguments); + } + + CustomAttributeArgument ReadCustomAttributeElement (TypeReference type) + { + if (type.IsArray) + return ReadCustomAttributeFixedArrayArgument ((ArrayType) type); + + return new CustomAttributeArgument ( + type, + type.etype == ElementType.Object + ? ReadCustomAttributeElement (ReadCustomAttributeFieldOrPropType ()) + : ReadCustomAttributeElementValue (type)); + } + + object ReadCustomAttributeElementValue (TypeReference type) + { + var etype = type.etype; + + switch (etype) { + case ElementType.String: + return ReadUTF8String (); + case ElementType.None: + if (type.IsTypeOf ("System", "Type")) + return ReadTypeReference (); + + return ReadCustomAttributeEnum (type); + default: + return ReadPrimitiveValue (etype); + } + } + + object ReadPrimitiveValue (ElementType type) + { + switch (type) { + case ElementType.Boolean: + return ReadByte () == 1; + case ElementType.I1: + return (sbyte) ReadByte (); + case ElementType.U1: + return ReadByte (); + case ElementType.Char: + return (char) ReadUInt16 (); + case ElementType.I2: + return ReadInt16 (); + case ElementType.U2: + return ReadUInt16 (); + case ElementType.I4: + return ReadInt32 (); + case ElementType.U4: + return ReadUInt32 (); + case ElementType.I8: + return ReadInt64 (); + case ElementType.U8: + return ReadUInt64 (); + case ElementType.R4: + return ReadSingle (); + case ElementType.R8: + return ReadDouble (); + default: + throw new NotImplementedException (type.ToString ()); + } + } + + TypeReference GetPrimitiveType (ElementType etype) + { + switch (etype) { + case ElementType.Boolean: + return TypeSystem.Boolean; + case ElementType.Char: + return TypeSystem.Char; + case ElementType.I1: + return TypeSystem.SByte; + case ElementType.U1: + return TypeSystem.Byte; + case ElementType.I2: + return TypeSystem.Int16; + case ElementType.U2: + return TypeSystem.UInt16; + case ElementType.I4: + return TypeSystem.Int32; + case ElementType.U4: + return TypeSystem.UInt32; + case ElementType.I8: + return TypeSystem.Int64; + case ElementType.U8: + return TypeSystem.UInt64; + case ElementType.R4: + return TypeSystem.Single; + case ElementType.R8: + return TypeSystem.Double; + case ElementType.String: + return TypeSystem.String; + default: + throw new NotImplementedException (etype.ToString ()); + } + } + + TypeReference ReadCustomAttributeFieldOrPropType () + { + var etype = (ElementType) ReadByte (); + + switch (etype) { + case ElementType.Boxed: + return TypeSystem.Object; + case ElementType.SzArray: + return new ArrayType (ReadCustomAttributeFieldOrPropType ()); + case ElementType.Enum: + return ReadTypeReference (); + case ElementType.Type: + return TypeSystem.LookupType ("System", "Type"); + default: + return GetPrimitiveType (etype); + } + } + + public TypeReference ReadTypeReference () + { + return TypeParser.ParseType (reader.module, ReadUTF8String ()); + } + + object ReadCustomAttributeEnum (TypeReference enum_type) + { + try + { + var type = enum_type.CheckedResolve (); + if (!type.IsEnum) + throw new ArgumentException (); + + return ReadCustomAttributeElementValue (type.GetEnumUnderlyingType ()); + } + catch + { + //Resolve failed + string name = enum_type.FullName + ", " + enum_type.scope.Name; + Type type = Type.GetType(name); + if (type == null || !type.IsEnum) + return new ArgumentException(); + var fields = type.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public); + Type eType = null; + foreach(var i in fields) + { + eType = i.FieldType; + break; + } + + object val; + if(eType == typeof(int)) + { + val = ReadPrimitiveValue(ElementType.I4); + } + else if (eType == typeof(long)) + { + val = ReadPrimitiveValue(ElementType.I8); + } + else if (eType == typeof(short)) + { + val = ReadPrimitiveValue(ElementType.I2); + } + else if (eType == typeof(byte)) + { + val = ReadPrimitiveValue(ElementType.U1); + } + else if (eType == typeof(uint)) + { + val = ReadPrimitiveValue(ElementType.U4); + } + else if (eType == typeof(ulong)) + { + val = ReadPrimitiveValue(ElementType.U8); + } + else if (eType == typeof(ushort)) + { + val = ReadPrimitiveValue(ElementType.U2); + } + else + { + val = ReadPrimitiveValue(ElementType.Void); + } + + return Enum.ToObject(type, val); + } + } + + public SecurityAttribute ReadSecurityAttribute () + { + var attribute = new SecurityAttribute (ReadTypeReference ()); + + ReadCompressedUInt32 (); + + ReadCustomAttributeNamedArguments ( + (ushort) ReadCompressedUInt32 (), + ref attribute.fields, + ref attribute.properties); + + return attribute; + } + + public MarshalInfo ReadMarshalInfo () + { + var native = ReadNativeType (); + switch (native) { + case NativeType.Array: { + var array = new ArrayMarshalInfo (); + if (CanReadMore ()) + array.element_type = ReadNativeType (); + if (CanReadMore ()) + array.size_parameter_index = (int) ReadCompressedUInt32 (); + if (CanReadMore ()) + array.size = (int) ReadCompressedUInt32 (); + if (CanReadMore ()) + array.size_parameter_multiplier = (int) ReadCompressedUInt32 (); + return array; + } + case NativeType.SafeArray: { + var array = new SafeArrayMarshalInfo (); + if (CanReadMore ()) + array.element_type = ReadVariantType (); + return array; + } + case NativeType.FixedArray: { + var array = new FixedArrayMarshalInfo (); + if (CanReadMore ()) + array.size = (int) ReadCompressedUInt32 (); + if (CanReadMore ()) + array.element_type = ReadNativeType (); + return array; + } + case NativeType.FixedSysString: { + var sys_string = new FixedSysStringMarshalInfo (); + if (CanReadMore ()) + sys_string.size = (int) ReadCompressedUInt32 (); + return sys_string; + } + case NativeType.CustomMarshaler: { + var marshaler = new CustomMarshalInfo (); + var guid_value = ReadUTF8String (); + marshaler.guid = !string.IsNullOrEmpty (guid_value) ? new Guid (guid_value) : Guid.Empty; + marshaler.unmanaged_type = ReadUTF8String (); + marshaler.managed_type = ReadTypeReference (); + marshaler.cookie = ReadUTF8String (); + return marshaler; + } + default: + return new MarshalInfo (native); + } + } + + NativeType ReadNativeType () + { + return (NativeType) ReadByte (); + } + + VariantType ReadVariantType () + { + return (VariantType) ReadByte (); + } + + string ReadUTF8String () + { + if (buffer [position] == 0xff) { + position++; + return null; + } + + var length = (int) ReadCompressedUInt32 (); + if (length == 0) + return string.Empty; + + var @string = Encoding.UTF8.GetString (buffer, position, + buffer [position + length - 1] == 0 ? length - 1 : length); + + position += length; + 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); + + uint part = ReadCompressedUInt32 (); + if (part != 0) + builder.Append (reader.ReadUTF8StringBlob (part)); + } + + return builder.ToString (); + } + + public Collection ReadSequencePoints (Document document) + { + var sequence_points = new Collection (); + + ReadCompressedUInt32 (); // local_sig_token + + if (document == null) + document = reader.GetDocument (ReadCompressedUInt32 ()); + + var offset = 1; + 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.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, + EndLine = 0xfeefee, + StartColumn = 0, + EndColumn = 0, + }); + 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.20/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil.20/Mono.Cecil/AssemblyWriter.cs new file mode 100644 index 00000000..ff8d3a18 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/AssemblyWriter.cs @@ -0,0 +1,3286 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Text; + +using Mono; +using Mono.Collections.Generic; +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; + +using RVA = System.UInt32; +using RID = System.UInt32; +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; + using MethodRow = Row; + using ParamRow = Row; + using InterfaceImplRow = Row; + using MemberRefRow = Row; + using ConstantRow = Row; + using CustomAttributeRow = Row; + using FieldMarshalRow = Row; + using DeclSecurityRow = Row; + using ClassLayoutRow = Row; + using FieldLayoutRow = Row; + using EventMapRow = Row; + using EventRow = Row; + using PropertyMapRow = Row; + using PropertyRow = Row; + using MethodSemanticsRow = Row; + using MethodImplRow = Row; + using ImplMapRow = Row; + using FieldRVARow = Row; + using AssemblyRow = Row; + using AssemblyRefRow = Row; + using FileRow = Row; + using ExportedTypeRow = Row; + using ManifestResourceRow = Row; + using NestedClassRow = Row; + 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 { + + public static void WriteModule (ModuleDefinition module, Disposable stream, WriterParameters parameters) + { + using (stream) + Write (module, stream, parameters); + } + + static void Write (ModuleDefinition module, Disposable stream, WriterParameters parameters) + { + if ((module.Attributes & ModuleAttributes.ILOnly) == 0) + throw new NotSupportedException ("Writing mixed-mode assemblies is not supported"); + + if (module.HasImage && module.ReadingMode == ReadingMode.Deferred) { + var immediate_reader = new ImmediateModuleReader (module.Image); + immediate_reader.ReadModule (module, resolve_attributes: false); + immediate_reader.ReadSymbols (module); + } + + module.MetadataSystem.Clear (); + + if (module.symbol_reader != null) + module.symbol_reader.Dispose (); + + var name = module.assembly != null ? module.assembly.Name : null; + var fq_name = stream.value.GetFileName (); + var timestamp = parameters.Timestamp ?? module.timestamp; + var symbol_writer_provider = parameters.SymbolWriterProvider; + + if (symbol_writer_provider == null && parameters.WriteSymbols) + symbol_writer_provider = new DefaultSymbolWriterProvider (); + +#if !NET_CORE + if (parameters.StrongNameKeyPair != null && name != null) { + name.PublicKey = parameters.StrongNameKeyPair.PublicKey; + module.Attributes |= ModuleAttributes.StrongNameSigned; + } +#endif + + using (var symbol_writer = GetSymbolWriter (module, fq_name, symbol_writer_provider, parameters)) { + var metadata = new MetadataBuilder (module, fq_name, timestamp, symbol_writer_provider, symbol_writer); + BuildMetadata (module, metadata); + + var writer = ImageWriter.CreateWriter (module, metadata, stream); + stream.value.SetLength (0); + writer.WriteImage (); + +#if !NET_CORE + if (parameters.StrongNameKeyPair != null) + CryptoService.StrongName (stream.value, writer, parameters.StrongNameKeyPair); +#endif + } + } + + static void BuildMetadata (ModuleDefinition module, MetadataBuilder metadata) + { + if (!module.HasImage) { + metadata.BuildMetadata (); + return; + } + + module.Read (metadata, (builder, _) => { + builder.BuildMetadata (); + return builder; + }); + } + + static ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider, WriterParameters parameters) + { + if (symbol_writer_provider == null) + return null; + + if (parameters.SymbolStream != null) + return symbol_writer_provider.GetSymbolWriter (module, parameters.SymbolStream); + + return symbol_writer_provider.GetSymbolWriter (module, fq_name); + } + } + + abstract class MetadataTable { + + public abstract int Length { get; } + + public bool IsLarge { + get { return Length > ushort.MaxValue; } + } + + public abstract void Write (TableHeapBuffer buffer); + public abstract void Sort (); + } + + abstract class OneRowTable : MetadataTable where TRow : struct { + + internal TRow row; + + public sealed override int Length { + get { return 1; } + } + + public sealed override void Sort () + { + } + } + + abstract class MetadataTable : MetadataTable where TRow : struct { + + internal TRow [] rows = new TRow [2]; + internal int length; + + public sealed override int Length { + get { return length; } + } + + public int AddRow (TRow row) + { + if (rows.Length == length) + Grow (); + + rows [length++] = row; + return length; + } + + void Grow () + { + var rows = new TRow [this.rows.Length * 2]; + Array.Copy (this.rows, rows, this.rows.Length); + this.rows = rows; + } + + public override void Sort () + { + } + } + + abstract class SortedTable : MetadataTable, IComparer where TRow : struct { + + public sealed override void Sort () + { + Array.Sort (rows, 0, length, this); + } + + protected int Compare (uint x, uint y) + { + return x == y ? 0 : x > y ? 1 : -1; + } + + public abstract int Compare (TRow x, TRow y); + } + + sealed class ModuleTable : OneRowTable { + + public override void Write (TableHeapBuffer buffer) + { + buffer.WriteUInt16 (0); // Generation + buffer.WriteString (row.Col1); // Name + buffer.WriteGuid (row.Col2); // Mvid + buffer.WriteUInt16 (0); // EncId + buffer.WriteUInt16 (0); // EncBaseId + } + } + + sealed class TypeRefTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID ( + rows [i].Col1, CodedIndex.ResolutionScope); // Scope + buffer.WriteString (rows [i].Col2); // Name + buffer.WriteString (rows [i].Col3); // Namespace + } + } + } + + sealed class TypeDefTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 ((uint) rows [i].Col1); // Attributes + buffer.WriteString (rows [i].Col2); // Name + buffer.WriteString (rows [i].Col3); // Namespace + buffer.WriteCodedRID ( + rows [i].Col4, CodedIndex.TypeDefOrRef); // Extends + buffer.WriteRID (rows [i].Col5, Table.Field); // FieldList + buffer.WriteRID (rows [i].Col6, Table.Method); // MethodList + } + } + } + + sealed class FieldTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes + buffer.WriteString (rows [i].Col2); // Name + buffer.WriteBlob (rows [i].Col3); // Signature + } + } + } + + sealed class MethodTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 (rows [i].Col1); // RVA + buffer.WriteUInt16 ((ushort) rows [i].Col2); // ImplFlags + buffer.WriteUInt16 ((ushort) rows [i].Col3); // Flags + buffer.WriteString (rows [i].Col4); // Name + buffer.WriteBlob (rows [i].Col5); // Signature + buffer.WriteRID (rows [i].Col6, Table.Param); // ParamList + } + } + } + + sealed class ParamTable : 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); // Sequence + buffer.WriteString (rows [i].Col3); // Name + } + } + } + + sealed class InterfaceImplTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Interface + } + } + + /*public override int Compare (InterfaceImplRow x, InterfaceImplRow y) + { + return (int) (x.Col1 == y.Col1 ? y.Col2 - x.Col2 : x.Col1 - y.Col1); + }*/ + } + + sealed class MemberRefTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MemberRefParent); + buffer.WriteString (rows [i].Col2); + buffer.WriteBlob (rows [i].Col3); + } + } + } + + sealed class ConstantTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasConstant); + buffer.WriteBlob (rows [i].Col3); + } + } + + public override int Compare (ConstantRow x, ConstantRow y) + { + return Compare (x.Col2, y.Col2); + } + } + + sealed class CustomAttributeTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomAttribute); // Parent + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.CustomAttributeType); // Type + buffer.WriteBlob (rows [i].Col3); + } + } + + public override int Compare (CustomAttributeRow x, CustomAttributeRow y) + { + return Compare (x.Col1, y.Col1); + } + } + + sealed class FieldMarshalTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasFieldMarshal); + buffer.WriteBlob (rows [i].Col2); + } + } + + public override int Compare (FieldMarshalRow x, FieldMarshalRow y) + { + return Compare (x.Col1, y.Col1); + } + } + + sealed class DeclSecurityTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasDeclSecurity); + buffer.WriteBlob (rows [i].Col3); + } + } + + public override int Compare (DeclSecurityRow x, DeclSecurityRow y) + { + return Compare (x.Col2, y.Col2); + } + } + + sealed class ClassLayoutTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 (rows [i].Col1); // PackingSize + buffer.WriteUInt32 (rows [i].Col2); // ClassSize + buffer.WriteRID (rows [i].Col3, Table.TypeDef); // Parent + } + } + + public override int Compare (ClassLayoutRow x, ClassLayoutRow y) + { + return Compare (x.Col3, y.Col3); + } + } + + sealed class FieldLayoutTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 (rows [i].Col1); // Offset + buffer.WriteRID (rows [i].Col2, Table.Field); // Parent + } + } + + public override int Compare (FieldLayoutRow x, FieldLayoutRow y) + { + return Compare (x.Col2, y.Col2); + } + } + + sealed class StandAloneSigTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) + buffer.WriteBlob (rows [i]); + } + } + + sealed class EventMapTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent + buffer.WriteRID (rows [i].Col2, Table.Event); // EventList + } + } + } + + sealed class EventTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags + buffer.WriteString (rows [i].Col2); // Name + buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeDefOrRef); // EventType + } + } + } + + sealed class PropertyMapTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent + buffer.WriteRID (rows [i].Col2, Table.Property); // PropertyList + } + } + } + + sealed class PropertyTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags + buffer.WriteString (rows [i].Col2); // Name + buffer.WriteBlob (rows [i].Col3); // Type + } + } + } + + sealed class MethodSemanticsTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags + buffer.WriteRID (rows [i].Col2, Table.Method); // Method + buffer.WriteCodedRID (rows [i].Col3, CodedIndex.HasSemantics); // Association + } + } + + public override int Compare (MethodSemanticsRow x, MethodSemanticsRow y) + { + return Compare (x.Col3, y.Col3); + } + } + + sealed class MethodImplTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MethodDefOrRef); // MethodBody + buffer.WriteCodedRID (rows [i].Col3, CodedIndex.MethodDefOrRef); // MethodDeclaration + } + } + } + + sealed class ModuleRefTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) + buffer.WriteString (rows [i]); // Name + } + } + + sealed class TypeSpecTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) + buffer.WriteBlob (rows [i]); // Signature + } + } + + sealed class ImplMapTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MemberForwarded); // MemberForwarded + buffer.WriteString (rows [i].Col3); // ImportName + buffer.WriteRID (rows [i].Col4, Table.ModuleRef); // ImportScope + } + } + + public override int Compare (ImplMapRow x, ImplMapRow y) + { + return Compare (x.Col2, y.Col2); + } + } + + sealed class FieldRVATable : SortedTable { + + internal int position; + + public override void Write (TableHeapBuffer buffer) + { + position = buffer.position; + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 (rows [i].Col1); // RVA + buffer.WriteRID (rows [i].Col2, Table.Field); // Field + } + } + + public override int Compare (FieldRVARow x, FieldRVARow y) + { + return Compare (x.Col2, y.Col2); + } + } + + sealed class AssemblyTable : OneRowTable { + + public override void Write (TableHeapBuffer buffer) + { + buffer.WriteUInt32 ((uint) row.Col1); // AssemblyHashAlgorithm + buffer.WriteUInt16 (row.Col2); // MajorVersion + buffer.WriteUInt16 (row.Col3); // MinorVersion + buffer.WriteUInt16 (row.Col4); // Build + buffer.WriteUInt16 (row.Col5); // Revision + buffer.WriteUInt32 ((uint) row.Col6); // Flags + buffer.WriteBlob (row.Col7); // PublicKey + buffer.WriteString (row.Col8); // Name + buffer.WriteString (row.Col9); // Culture + } + } + + sealed class AssemblyRefTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 (rows [i].Col1); // MajorVersion + buffer.WriteUInt16 (rows [i].Col2); // MinorVersion + buffer.WriteUInt16 (rows [i].Col3); // Build + buffer.WriteUInt16 (rows [i].Col4); // Revision + buffer.WriteUInt32 ((uint) rows [i].Col5); // Flags + buffer.WriteBlob (rows [i].Col6); // PublicKeyOrToken + buffer.WriteString (rows [i].Col7); // Name + buffer.WriteString (rows [i].Col8); // Culture + buffer.WriteBlob (rows [i].Col9); // Hash + } + } + } + + sealed class FileTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 ((uint) rows [i].Col1); + buffer.WriteString (rows [i].Col2); + buffer.WriteBlob (rows [i].Col3); + } + } + } + + sealed class ExportedTypeTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 ((uint) rows [i].Col1); + buffer.WriteUInt32 (rows [i].Col2); + buffer.WriteString (rows [i].Col3); + buffer.WriteString (rows [i].Col4); + buffer.WriteCodedRID (rows [i].Col5, CodedIndex.Implementation); + } + } + } + + sealed class ManifestResourceTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 (rows [i].Col1); + buffer.WriteUInt32 ((uint) rows [i].Col2); + buffer.WriteString (rows [i].Col3); + buffer.WriteCodedRID (rows [i].Col4, CodedIndex.Implementation); + } + } + } + + sealed class NestedClassTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.TypeDef); // NestedClass + buffer.WriteRID (rows [i].Col2, Table.TypeDef); // EnclosingClass + } + } + + public override int Compare (NestedClassRow x, NestedClassRow y) + { + return Compare (x.Col1, y.Col1); + } + } + + sealed class GenericParamTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 (rows [i].Col1); // Number + buffer.WriteUInt16 ((ushort) rows [i].Col2); // Flags + buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeOrMethodDef); // Owner + buffer.WriteString (rows [i].Col4); // Name + } + } + } + + sealed class MethodSpecTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MethodDefOrRef); // Method + buffer.WriteBlob (rows [i].Col2); // Instantiation + } + } + } + + sealed class GenericParamConstraintTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.GenericParam); // Owner + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Constraint + } + } + } + + 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 : SortedTable { + + 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 + } + } + + public override int Compare (CustomDebugInformationRow x, CustomDebugInformationRow y) + { + return Compare(x.Col1, y.Col1); + } + } + + sealed class MetadataBuilder { + + readonly internal ModuleDefinition module; + readonly internal ISymbolWriterProvider symbol_writer_provider; + readonly internal ISymbolWriter symbol_writer; + readonly internal TextMap text_map; + readonly internal string fq_name; + readonly internal uint timestamp; + + readonly Dictionary type_ref_map; + readonly Dictionary type_spec_map; + readonly Dictionary member_ref_map; + readonly Dictionary method_spec_map; + readonly Collection generic_parameters; + + 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; + + 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; + readonly FieldTable field_table; + readonly MethodTable method_table; + readonly ParamTable param_table; + readonly InterfaceImplTable iface_impl_table; + readonly MemberRefTable member_ref_table; + readonly ConstantTable constant_table; + readonly CustomAttributeTable custom_attribute_table; + readonly DeclSecurityTable declsec_table; + readonly StandAloneSigTable standalone_sig_table; + readonly EventMapTable event_map_table; + readonly EventTable event_table; + readonly PropertyMapTable property_map_table; + readonly PropertyTable property_table; + 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; + + public MetadataBuilder (ModuleDefinition module, string fq_name, uint timestamp, ISymbolWriterProvider symbol_writer_provider, ISymbolWriter symbol_writer) + { + this.module = module; + this.text_map = CreateTextMap (); + this.fq_name = fq_name; + this.timestamp = timestamp; + 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; + + var pdb_writer = symbol_writer as IMetadataSymbolWriter; + if (pdb_writer != null) { + portable_pdb = true; + pdb_writer.SetMetadata (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); + + this.type_ref_table = GetTable (Table.TypeRef); + this.type_def_table = GetTable (Table.TypeDef); + this.field_table = GetTable (Table.Field); + this.method_table = GetTable (Table.Method); + this.param_table = GetTable (Table.Param); + this.iface_impl_table = GetTable (Table.InterfaceImpl); + this.member_ref_table = GetTable (Table.MemberRef); + this.constant_table = GetTable (Table.Constant); + this.custom_attribute_table = GetTable (Table.CustomAttribute); + this.declsec_table = GetTable (Table.DeclSecurity); + this.standalone_sig_table = GetTable (Table.StandAloneSig); + this.event_map_table = GetTable (Table.EventMap); + this.event_table = GetTable (Table.Event); + this.property_map_table = GetTable (Table.PropertyMap); + this.property_table = GetTable (Table.Property); + this.typespec_table = GetTable (Table.TypeSpec); + this.method_spec_table = GetTable (Table.MethodSpec); + + var row_equality_comparer = new RowEqualityComparer (); + type_ref_map = new Dictionary (row_equality_comparer); + type_spec_map = new Dictionary (); + member_ref_map = new Dictionary (row_equality_comparer); + method_spec_map = new Dictionary (row_equality_comparer); + generic_parameters = new Collection (); + + 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 () + { + var map = new TextMap (); + map.AddMap (TextSegment.ImportAddressTable, module.Architecture == TargetArchitecture.I386 ? 8 : 0); + map.AddMap (TextSegment.CLIHeader, 0x48, 8); + return map; + } + + TTable GetTable (Table table) where TTable : MetadataTable, new () + { + return table_heap.GetTable (table); + } + + uint GetStringIndex (string @string) + { + if (string.IsNullOrEmpty (@string)) + return 0; + + return string_heap.GetStringIndex (@string); + } + + uint GetGuidIndex (Guid guid) + { + return guid_heap.GetGuidIndex (guid); + } + + uint GetBlobIndex (ByteBuffer blob) + { + if (blob.length == 0) + return 0; + + return blob_heap.GetBlobIndex (blob); + } + + uint GetBlobIndex (byte [] blob) + { + if (blob.IsNullOrEmpty ()) + return 0; + + return GetBlobIndex (new ByteBuffer (blob)); + } + + public void BuildMetadata () + { + BuildModule (); + + table_heap.string_offsets = string_heap.WriteStrings (); + table_heap.ComputeTableInformations (); + table_heap.WriteTableHeap (); + } + + void BuildModule () + { + var table = GetTable (Table.Module); + table.row.Col1 = GetStringIndex (module.Name); + table.row.Col2 = GetGuidIndex (module.Mvid); + + var assembly = module.Assembly; + + if (assembly != null) + BuildAssembly (); + + if (module.HasAssemblyReferences) + AddAssemblyReferences (); + + if (module.HasModuleReferences) + AddModuleReferences (); + + if (module.HasResources) + AddResources (); + + if (module.HasExportedTypes) + AddExportedTypes (); + + BuildTypes (); + + if (assembly != null) { + if (assembly.HasCustomAttributes) + AddCustomAttributes (assembly); + + if (assembly.HasSecurityDeclarations) + AddSecurityDeclarations (assembly); + } + + if (module.HasCustomAttributes) + AddCustomAttributes (module); + + if (module.EntryPoint != null) + entry_point = LookupToken (module.EntryPoint); + + var pdb_writer = symbol_writer as IMetadataSymbolWriter; + if (pdb_writer != null) + pdb_writer.WriteModule (); + } + + void BuildAssembly () + { + var assembly = module.Assembly; + var name = assembly.Name; + + var table = GetTable (Table.Assembly); + + table.row = new AssemblyRow ( + name.HashAlgorithm, + (ushort) name.Version.Major, + (ushort) name.Version.Minor, + (ushort) name.Version.Build, + (ushort) name.Version.Revision, + name.Attributes, + GetBlobIndex (name.PublicKey), + GetStringIndex (name.Name), + GetStringIndex (name.Culture)); + + if (assembly.Modules.Count > 1) + BuildModules (); + } + + void BuildModules () + { + var modules = this.module.Assembly.Modules; + var table = GetTable (Table.File); + + for (int i = 0; i < modules.Count; i++) { + var module = modules [i]; + if (module.IsMain) + continue; + +#if NET_CORE + throw new NotSupportedException (); +#else + var parameters = new WriterParameters { + SymbolWriterProvider = symbol_writer_provider, + }; + + var file_name = GetModuleFileName (module.Name); + module.Write (file_name, parameters); + + var hash = CryptoService.ComputeHash (file_name); + + table.AddRow (new FileRow ( + FileAttributes.ContainsMetaData, + GetStringIndex (module.Name), + GetBlobIndex (hash))); +#endif + } + } + +#if !NET_CORE + string GetModuleFileName (string name) + { + if (string.IsNullOrEmpty (name)) + throw new NotSupportedException (); + + var path = Path.GetDirectoryName (fq_name); + return Path.Combine (path, name); + } +#endif + + void AddAssemblyReferences () + { + var references = module.AssemblyReferences; + var table = GetTable (Table.AssemblyRef); + + if (module.IsWindowsMetadata ()) + module.Projections.RemoveVirtualReferences (references); + + for (int i = 0; i < references.Count; i++) { + var reference = references [i]; + + var key_or_token = reference.PublicKey.IsNullOrEmpty () + ? reference.PublicKeyToken + : reference.PublicKey; + + var version = reference.Version; + + var rid = table.AddRow (new AssemblyRefRow ( + (ushort) version.Major, + (ushort) version.Minor, + (ushort) version.Build, + (ushort) version.Revision, + reference.Attributes, + GetBlobIndex (key_or_token), + GetStringIndex (reference.Name), + GetStringIndex (reference.Culture), + GetBlobIndex (reference.Hash))); + + reference.token = new MetadataToken (TokenType.AssemblyRef, rid); + } + + if (module.IsWindowsMetadata ()) + module.Projections.AddVirtualReferences (references); + } + + void AddModuleReferences () + { + var references = module.ModuleReferences; + var table = GetTable (Table.ModuleRef); + + for (int i = 0; i < references.Count; i++) { + var reference = references [i]; + + reference.token = new MetadataToken ( + TokenType.ModuleRef, + table.AddRow (GetStringIndex (reference.Name))); + } + } + + void AddResources () + { + var resources = module.Resources; + var table = GetTable (Table.ManifestResource); + + for (int i = 0; i < resources.Count; i++) { + var resource = resources [i]; + + var row = new ManifestResourceRow ( + 0, + resource.Attributes, + GetStringIndex (resource.Name), + 0); + + switch (resource.ResourceType) { + case ResourceType.Embedded: + row.Col1 = AddEmbeddedResource ((EmbeddedResource) resource); + break; + case ResourceType.Linked: + row.Col4 = CodedIndex.Implementation.CompressMetadataToken ( + new MetadataToken ( + TokenType.File, + AddLinkedResource ((LinkedResource) resource))); + break; + case ResourceType.AssemblyLinked: + row.Col4 = CodedIndex.Implementation.CompressMetadataToken ( + ((AssemblyLinkedResource) resource).Assembly.MetadataToken); + break; + default: + throw new NotSupportedException (); + } + + table.AddRow (row); + } + } + + uint AddLinkedResource (LinkedResource resource) + { + var table = GetTable (Table.File); + var hash = resource.Hash; + +#if !NET_CORE + if (hash.IsNullOrEmpty ()) + hash = CryptoService.ComputeHash (resource.File); +#endif + + return (uint) table.AddRow (new FileRow ( + FileAttributes.ContainsNoMetaData, + GetStringIndex (resource.File), + GetBlobIndex (hash))); + } + + uint AddEmbeddedResource (EmbeddedResource resource) + { + return resources.AddResource (resource.GetResourceData ()); + } + + void AddExportedTypes () + { + var exported_types = module.ExportedTypes; + var table = GetTable (Table.ExportedType); + + for (int i = 0; i < exported_types.Count; i++) { + var exported_type = exported_types [i]; + + var rid = table.AddRow (new ExportedTypeRow ( + exported_type.Attributes, + (uint) exported_type.Identifier, + GetStringIndex (exported_type.Name), + GetStringIndex (exported_type.Namespace), + MakeCodedRID (GetExportedTypeScope (exported_type), CodedIndex.Implementation))); + + exported_type.token = new MetadataToken (TokenType.ExportedType, rid); + } + } + + MetadataToken GetExportedTypeScope (ExportedType exported_type) + { + if (exported_type.DeclaringType != null) + return exported_type.DeclaringType.MetadataToken; + + var scope = exported_type.Scope; + switch (scope.MetadataToken.TokenType) { + case TokenType.AssemblyRef: + return scope.MetadataToken; + case TokenType.ModuleRef: + var file_table = GetTable (Table.File); + for (int i = 0; i < file_table.length; i++) + if (file_table.rows [i].Col2 == GetStringIndex (scope.Name)) + return new MetadataToken (TokenType.File, i + 1); + + break; + } + + throw new NotSupportedException (); + } + + void BuildTypes () + { + if (!module.HasTypes) + return; + + AttachTokens (); + AddTypes (); + AddGenericParameters (); + } + + void AttachTokens () + { + var types = module.Types; + + for (int i = 0; i < types.Count; i++) + AttachTypeToken (types [i]); + } + + void AttachTypeToken (TypeDefinition type) + { + type.token = new MetadataToken (TokenType.TypeDef, type_rid++); + type.fields_range.Start = field_rid; + type.methods_range.Start = method_rid; + + if (type.HasFields) + AttachFieldsToken (type); + + if (type.HasMethods) + AttachMethodsToken (type); + + if (type.HasNestedTypes) + AttachNestedTypesToken (type); + } + + void AttachNestedTypesToken (TypeDefinition type) + { + var nested_types = type.NestedTypes; + for (int i = 0; i < nested_types.Count; i++) + AttachTypeToken (nested_types [i]); + } + + void AttachFieldsToken (TypeDefinition type) + { + var fields = type.Fields; + type.fields_range.Length = (uint) fields.Count; + for (int i = 0; i < fields.Count; i++) + fields [i].token = new MetadataToken (TokenType.Field, field_rid++); + } + + void AttachMethodsToken (TypeDefinition type) + { + var methods = type.Methods; + type.methods_range.Length = (uint) methods.Count; + for (int i = 0; i < methods.Count; i++) + methods [i].token = new MetadataToken (TokenType.Method, method_rid++); + } + + MetadataToken GetTypeToken (TypeReference type) + { + if (type == null) + return MetadataToken.Zero; + + if (type.IsDefinition) + return type.token; + + if (type.IsTypeSpecification ()) + return GetTypeSpecToken (type); + + return GetTypeRefToken (type); + } + + MetadataToken GetTypeSpecToken (TypeReference type) + { + var row = GetBlobIndex (GetTypeSpecSignature (type)); + + MetadataToken token; + if (type_spec_map.TryGetValue (row, out token)) + return token; + + return AddTypeSpecification (type, row); + } + + MetadataToken AddTypeSpecification (TypeReference type, uint row) + { + type.token = new MetadataToken (TokenType.TypeSpec, typespec_table.AddRow (row)); + + var token = type.token; + type_spec_map.Add (row, token); + return token; + } + + MetadataToken GetTypeRefToken (TypeReference type) + { + var projection = WindowsRuntimeProjections.RemoveProjection (type); + + var row = CreateTypeRefRow (type); + + MetadataToken token; + if (!type_ref_map.TryGetValue (row, out token)) + token = AddTypeReference (type, row); + + WindowsRuntimeProjections.ApplyProjection (type, projection); + + return token; + } + + TypeRefRow CreateTypeRefRow (TypeReference type) + { + var scope_token = GetScopeToken (type); + + return new TypeRefRow ( + MakeCodedRID (scope_token, CodedIndex.ResolutionScope), + GetStringIndex (type.Name), + GetStringIndex (type.Namespace)); + } + + MetadataToken GetScopeToken (TypeReference type) + { + if (type.IsNested) + return GetTypeRefToken (type.DeclaringType); + + var scope = type.Scope; + + if (scope == null) + return MetadataToken.Zero; + + return scope.MetadataToken; + } + + static CodedRID MakeCodedRID (IMetadataTokenProvider provider, CodedIndex index) + { + return MakeCodedRID (provider.MetadataToken, index); + } + + static CodedRID MakeCodedRID (MetadataToken token, CodedIndex index) + { + return index.CompressMetadataToken (token); + } + + MetadataToken AddTypeReference (TypeReference type, TypeRefRow row) + { + type.token = new MetadataToken (TokenType.TypeRef, type_ref_table.AddRow (row)); + + var token = type.token; + type_ref_map.Add (row, token); + return token; + } + + void AddTypes () + { + var types = module.Types; + + for (int i = 0; i < types.Count; i++) + AddType (types [i]); + } + + void AddType (TypeDefinition type) + { + var treatment = WindowsRuntimeProjections.RemoveProjection (type); + + type_def_table.AddRow (new TypeDefRow ( + type.Attributes, + GetStringIndex (type.Name), + GetStringIndex (type.Namespace), + MakeCodedRID (GetTypeToken (type.BaseType), CodedIndex.TypeDefOrRef), + type.fields_range.Start, + type.methods_range.Start)); + + if (type.HasGenericParameters) + AddGenericParameters (type); + + if (type.HasInterfaces) + AddInterfaces (type); + + if (type.HasLayoutInfo) + AddLayoutInfo (type); + + if (type.HasFields) + AddFields (type); + + if (type.HasMethods) + AddMethods (type); + + if (type.HasProperties) + AddProperties (type); + + if (type.HasEvents) + AddEvents (type); + + if (type.HasCustomAttributes) + AddCustomAttributes (type); + + if (type.HasSecurityDeclarations) + AddSecurityDeclarations (type); + + if (type.HasNestedTypes) + AddNestedTypes (type); + + WindowsRuntimeProjections.ApplyProjection (type, treatment); + } + + void AddGenericParameters (IGenericParameterProvider owner) + { + var parameters = owner.GenericParameters; + + for (int i = 0; i < parameters.Count; i++) + generic_parameters.Add (parameters [i]); + } + + sealed class GenericParameterComparer : IComparer { + + public int Compare (GenericParameter a, GenericParameter b) + { + var a_owner = MakeCodedRID (a.Owner, CodedIndex.TypeOrMethodDef); + var b_owner = MakeCodedRID (b.Owner, CodedIndex.TypeOrMethodDef); + if (a_owner == b_owner) { + var a_pos = a.Position; + var b_pos = b.Position; + return a_pos == b_pos ? 0 : a_pos > b_pos ? 1 : -1; + } + + return a_owner > b_owner ? 1 : -1; + } + } + + void AddGenericParameters () + { + var items = this.generic_parameters.items; + var size = this.generic_parameters.size; + Array.Sort (items, 0, size, new GenericParameterComparer ()); + + var generic_param_table = GetTable (Table.GenericParam); + var generic_param_constraint_table = GetTable (Table.GenericParamConstraint); + + for (int i = 0; i < size; i++) { + var generic_parameter = items [i]; + + var rid = generic_param_table.AddRow (new GenericParamRow ( + (ushort) generic_parameter.Position, + generic_parameter.Attributes, + MakeCodedRID (generic_parameter.Owner, CodedIndex.TypeOrMethodDef), + GetStringIndex (generic_parameter.Name))); + + generic_parameter.token = new MetadataToken (TokenType.GenericParam, rid); + + if (generic_parameter.HasConstraints) + AddConstraints (generic_parameter, generic_param_constraint_table); + + if (generic_parameter.HasCustomAttributes) + AddCustomAttributes (generic_parameter); + } + } + + void AddConstraints (GenericParameter generic_parameter, GenericParamConstraintTable table) + { + var constraints = generic_parameter.Constraints; + + var rid = generic_parameter.token.RID; + + for (int i = 0; i < constraints.Count; i++) + table.AddRow (new GenericParamConstraintRow ( + rid, + MakeCodedRID (GetTypeToken (constraints [i]), CodedIndex.TypeDefOrRef))); + } + + void AddInterfaces (TypeDefinition type) + { + var interfaces = type.Interfaces; + var type_rid = type.token.RID; + + for (int i = 0; i < interfaces.Count; i++) { + var iface_impl = interfaces [i]; + + var rid = iface_impl_table.AddRow (new InterfaceImplRow ( + type_rid, + MakeCodedRID (GetTypeToken (iface_impl.InterfaceType), CodedIndex.TypeDefOrRef))); + + iface_impl.token = new MetadataToken (TokenType.InterfaceImpl, rid); + + if (iface_impl.HasCustomAttributes) + AddCustomAttributes (iface_impl); + } + } + + void AddLayoutInfo (TypeDefinition type) + { + var table = GetTable (Table.ClassLayout); + + table.AddRow (new ClassLayoutRow ( + (ushort) type.PackingSize, + (uint) type.ClassSize, + type.token.RID)); + } + + void AddNestedTypes (TypeDefinition type) + { + var nested_types = type.NestedTypes; + var nested_table = GetTable (Table.NestedClass); + + for (int i = 0; i < nested_types.Count; i++) { + var nested = nested_types [i]; + AddType (nested); + nested_table.AddRow (new NestedClassRow (nested.token.RID, type.token.RID)); + } + } + + void AddFields (TypeDefinition type) + { + var fields = type.Fields; + + for (int i = 0; i < fields.Count; i++) + AddField (fields [i]); + } + + void AddField (FieldDefinition field) + { + var projection = WindowsRuntimeProjections.RemoveProjection (field); + + field_table.AddRow (new FieldRow ( + field.Attributes, + GetStringIndex (field.Name), + GetBlobIndex (GetFieldSignature (field)))); + + if (!field.InitialValue.IsNullOrEmpty ()) + AddFieldRVA (field); + + if (field.HasLayoutInfo) + AddFieldLayout (field); + + if (field.HasCustomAttributes) + AddCustomAttributes (field); + + if (field.HasConstant) + AddConstant (field, field.FieldType); + + if (field.HasMarshalInfo) + AddMarshalInfo (field); + + WindowsRuntimeProjections.ApplyProjection (field, projection); + } + + void AddFieldRVA (FieldDefinition field) + { + var table = GetTable (Table.FieldRVA); + table.AddRow (new FieldRVARow ( + data.AddData (field.InitialValue), + field.token.RID)); + } + + void AddFieldLayout (FieldDefinition field) + { + var table = GetTable (Table.FieldLayout); + table.AddRow (new FieldLayoutRow ((uint) field.Offset, field.token.RID)); + } + + void AddMethods (TypeDefinition type) + { + var methods = type.Methods; + + for (int i = 0; i < methods.Count; i++) + AddMethod (methods [i]); + } + + void AddMethod (MethodDefinition method) + { + var projection = WindowsRuntimeProjections.RemoveProjection (method); + + method_table.AddRow (new MethodRow ( + method.HasBody ? code.WriteMethodBody (method) : 0, + method.ImplAttributes, + method.Attributes, + GetStringIndex (method.Name), + GetBlobIndex (GetMethodSignature (method)), + param_rid)); + + AddParameters (method); + + if (method.HasGenericParameters) + AddGenericParameters (method); + + if (method.IsPInvokeImpl) + AddPInvokeInfo (method); + + if (method.HasCustomAttributes) + AddCustomAttributes (method); + + if (method.HasSecurityDeclarations) + AddSecurityDeclarations (method); + + if (method.HasOverrides) + AddOverrides (method); + + WindowsRuntimeProjections.ApplyProjection (method, projection); + } + + void AddParameters (MethodDefinition method) + { + var return_parameter = method.MethodReturnType.parameter; + + if (return_parameter != null && RequiresParameterRow (return_parameter)) + AddParameter (0, return_parameter, param_table); + + if (!method.HasParameters) + return; + + var parameters = method.Parameters; + + for (int i = 0; i < parameters.Count; i++) { + var parameter = parameters [i]; + if (!RequiresParameterRow (parameter)) + continue; + + AddParameter ((ushort) (i + 1), parameter, param_table); + } + } + + void AddPInvokeInfo (MethodDefinition method) + { + var pinvoke = method.PInvokeInfo; + if (pinvoke == null) + return; + + var table = GetTable (Table.ImplMap); + table.AddRow (new ImplMapRow ( + pinvoke.Attributes, + MakeCodedRID (method, CodedIndex.MemberForwarded), + GetStringIndex (pinvoke.EntryPoint), + pinvoke.Module.MetadataToken.RID)); + } + + void AddOverrides (MethodDefinition method) + { + var overrides = method.Overrides; + var table = GetTable (Table.MethodImpl); + + for (int i = 0; i < overrides.Count; i++) { + table.AddRow (new MethodImplRow ( + method.DeclaringType.token.RID, + MakeCodedRID (method, CodedIndex.MethodDefOrRef), + MakeCodedRID (LookupToken (overrides [i]), CodedIndex.MethodDefOrRef))); + } + } + + static bool RequiresParameterRow (ParameterDefinition parameter) + { + return !string.IsNullOrEmpty (parameter.Name) + || parameter.Attributes != ParameterAttributes.None + || parameter.HasMarshalInfo + || parameter.HasConstant + || parameter.HasCustomAttributes; + } + + void AddParameter (ushort sequence, ParameterDefinition parameter, ParamTable table) + { + table.AddRow (new ParamRow ( + parameter.Attributes, + sequence, + GetStringIndex (parameter.Name))); + + parameter.token = new MetadataToken (TokenType.Param, param_rid++); + + if (parameter.HasCustomAttributes) + AddCustomAttributes (parameter); + + if (parameter.HasConstant) + AddConstant (parameter, parameter.ParameterType); + + if (parameter.HasMarshalInfo) + AddMarshalInfo (parameter); + } + + void AddMarshalInfo (IMarshalInfoProvider owner) + { + var table = GetTable (Table.FieldMarshal); + + table.AddRow (new FieldMarshalRow ( + MakeCodedRID (owner, CodedIndex.HasFieldMarshal), + GetBlobIndex (GetMarshalInfoSignature (owner)))); + } + + void AddProperties (TypeDefinition type) + { + var properties = type.Properties; + + property_map_table.AddRow (new PropertyMapRow (type.token.RID, property_rid)); + + for (int i = 0; i < properties.Count; i++) + AddProperty (properties [i]); + } + + void AddProperty (PropertyDefinition property) + { + property_table.AddRow (new PropertyRow ( + property.Attributes, + GetStringIndex (property.Name), + GetBlobIndex (GetPropertySignature (property)))); + property.token = new MetadataToken (TokenType.Property, property_rid++); + + var method = property.GetMethod; + if (method != null) + AddSemantic (MethodSemanticsAttributes.Getter, property, method); + + method = property.SetMethod; + if (method != null) + AddSemantic (MethodSemanticsAttributes.Setter, property, method); + + if (property.HasOtherMethods) + AddOtherSemantic (property, property.OtherMethods); + + if (property.HasCustomAttributes) + AddCustomAttributes (property); + + if (property.HasConstant) + AddConstant (property, property.PropertyType); + } + + void AddOtherSemantic (IMetadataTokenProvider owner, Collection others) + { + for (int i = 0; i < others.Count; i++) + AddSemantic (MethodSemanticsAttributes.Other, owner, others [i]); + } + + void AddEvents (TypeDefinition type) + { + var events = type.Events; + + event_map_table.AddRow (new EventMapRow (type.token.RID, event_rid)); + + for (int i = 0; i < events.Count; i++) + AddEvent (events [i]); + } + + void AddEvent (EventDefinition @event) + { + event_table.AddRow (new EventRow ( + @event.Attributes, + GetStringIndex (@event.Name), + MakeCodedRID (GetTypeToken (@event.EventType), CodedIndex.TypeDefOrRef))); + @event.token = new MetadataToken (TokenType.Event, event_rid++); + + var method = @event.AddMethod; + if (method != null) + AddSemantic (MethodSemanticsAttributes.AddOn, @event, method); + + method = @event.InvokeMethod; + if (method != null) + AddSemantic (MethodSemanticsAttributes.Fire, @event, method); + + method = @event.RemoveMethod; + if (method != null) + AddSemantic (MethodSemanticsAttributes.RemoveOn, @event, method); + + if (@event.HasOtherMethods) + AddOtherSemantic (@event, @event.OtherMethods); + + if (@event.HasCustomAttributes) + AddCustomAttributes (@event); + } + + void AddSemantic (MethodSemanticsAttributes semantics, IMetadataTokenProvider provider, MethodDefinition method) + { + method.SemanticsAttributes = semantics; + var table = GetTable (Table.MethodSemantics); + + table.AddRow (new MethodSemanticsRow ( + semantics, + method.token.RID, + MakeCodedRID (provider, CodedIndex.HasSemantics))); + } + + void AddConstant (IConstantProvider owner, TypeReference type) + { + var constant = owner.Constant; + var etype = GetConstantType (type, constant); + + constant_table.AddRow (new ConstantRow ( + etype, + MakeCodedRID (owner.MetadataToken, CodedIndex.HasConstant), + GetBlobIndex (GetConstantSignature (etype, constant)))); + } + + static ElementType GetConstantType (TypeReference constant_type, object constant) + { + if (constant == null) + return ElementType.Class; + + var etype = constant_type.etype; + switch (etype) { + case ElementType.None: + var type = constant_type.CheckedResolve (); + if (type.IsEnum) + return GetConstantType (type.GetEnumUnderlyingType (), constant); + + return ElementType.Class; + case ElementType.String: + return ElementType.String; + case ElementType.Object: + return GetConstantType (constant.GetType ()); + case ElementType.Array: + case ElementType.SzArray: + case ElementType.MVar: + case ElementType.Var: + return ElementType.Class; + case ElementType.GenericInst: + var generic_instance = (GenericInstanceType) constant_type; + if (generic_instance.ElementType.IsTypeOf ("System", "Nullable`1")) + return GetConstantType (generic_instance.GenericArguments [0], constant); + + return GetConstantType (((TypeSpecification) constant_type).ElementType, constant); + case ElementType.CModOpt: + case ElementType.CModReqD: + case ElementType.ByRef: + case ElementType.Sentinel: + return GetConstantType (((TypeSpecification) constant_type).ElementType, constant); + case ElementType.Boolean: + case ElementType.Char: + case ElementType.I: + case ElementType.I1: + case ElementType.I2: + case ElementType.I4: + case ElementType.I8: + case ElementType.U: + case ElementType.U1: + case ElementType.U2: + case ElementType.U4: + case ElementType.U8: + case ElementType.R4: + case ElementType.R8: + return GetConstantType (constant.GetType ()); + default: + return etype; + } + } + + static ElementType GetConstantType (Type type) + { + switch (type.GetTypeCode ()) { + case TypeCode.Boolean: + return ElementType.Boolean; + case TypeCode.Byte: + return ElementType.U1; + case TypeCode.SByte: + return ElementType.I1; + case TypeCode.Char: + return ElementType.Char; + case TypeCode.Int16: + return ElementType.I2; + case TypeCode.UInt16: + return ElementType.U2; + case TypeCode.Int32: + return ElementType.I4; + case TypeCode.UInt32: + return ElementType.U4; + case TypeCode.Int64: + return ElementType.I8; + case TypeCode.UInt64: + return ElementType.U8; + case TypeCode.Single: + return ElementType.R4; + case TypeCode.Double: + return ElementType.R8; + case TypeCode.String: + return ElementType.String; + default: + throw new NotSupportedException (type.FullName); + } + } + + void AddCustomAttributes (ICustomAttributeProvider owner) + { + var custom_attributes = owner.CustomAttributes; + + for (int i = 0; i < custom_attributes.Count; i++) { + var attribute = custom_attributes [i]; + + var projection = WindowsRuntimeProjections.RemoveProjection (attribute); + + custom_attribute_table.AddRow (new CustomAttributeRow ( + MakeCodedRID (owner, CodedIndex.HasCustomAttribute), + MakeCodedRID (LookupToken (attribute.Constructor), CodedIndex.CustomAttributeType), + GetBlobIndex (GetCustomAttributeSignature (attribute)))); + + WindowsRuntimeProjections.ApplyProjection (attribute, projection); + } + } + + void AddSecurityDeclarations (ISecurityDeclarationProvider owner) + { + var declarations = owner.SecurityDeclarations; + + for (int i = 0; i < declarations.Count; i++) { + var declaration = declarations [i]; + + declsec_table.AddRow (new DeclSecurityRow ( + declaration.Action, + MakeCodedRID (owner, CodedIndex.HasDeclSecurity), + GetBlobIndex (GetSecurityDeclarationSignature (declaration)))); + } + } + + MetadataToken GetMemberRefToken (MemberReference member) + { + var projection = WindowsRuntimeProjections.RemoveProjection (member); + + var row = CreateMemberRefRow (member); + + MetadataToken token; + if (!member_ref_map.TryGetValue (row, out token)) + token = AddMemberReference (member, row); + + WindowsRuntimeProjections.ApplyProjection (member, projection); + + return token; + } + + MemberRefRow CreateMemberRefRow (MemberReference member) + { + return new MemberRefRow ( + MakeCodedRID (GetTypeToken (member.DeclaringType), CodedIndex.MemberRefParent), + GetStringIndex (member.Name), + GetBlobIndex (GetMemberRefSignature (member))); + } + + MetadataToken AddMemberReference (MemberReference member, MemberRefRow row) + { + member.token = new MetadataToken (TokenType.MemberRef, member_ref_table.AddRow (row)); + + var token = member.token; + member_ref_map.Add (row, token); + return token; + } + + MetadataToken GetMethodSpecToken (MethodSpecification method_spec) + { + var row = CreateMethodSpecRow (method_spec); + + MetadataToken token; + if (method_spec_map.TryGetValue (row, out token)) + return token; + + AddMethodSpecification (method_spec, row); + + return method_spec.token; + } + + void AddMethodSpecification (MethodSpecification method_spec, MethodSpecRow row) + { + method_spec.token = new MetadataToken (TokenType.MethodSpec, method_spec_table.AddRow (row)); + method_spec_map.Add (row, method_spec.token); + } + + MethodSpecRow CreateMethodSpecRow (MethodSpecification method_spec) + { + return new MethodSpecRow ( + MakeCodedRID (LookupToken (method_spec.ElementMethod), CodedIndex.MethodDefOrRef), + GetBlobIndex (GetMethodSpecSignature (method_spec))); + } + + SignatureWriter CreateSignatureWriter () + { + return new SignatureWriter (this); + } + + SignatureWriter GetMethodSpecSignature (MethodSpecification method_spec) + { + if (!method_spec.IsGenericInstance) + throw new NotSupportedException (); + + var generic_instance = (GenericInstanceMethod) method_spec; + + var signature = CreateSignatureWriter (); + signature.WriteByte (0x0a); + + signature.WriteGenericInstanceSignature (generic_instance); + + return signature; + } + + public uint AddStandAloneSignature (uint signature) + { + return (uint) standalone_sig_table.AddRow (signature); + } + + public uint GetLocalVariableBlobIndex (Collection variables) + { + return GetBlobIndex (GetVariablesSignature (variables)); + } + + public uint GetCallSiteBlobIndex (CallSite call_site) + { + return GetBlobIndex (GetMethodSignature (call_site)); + } + + public uint GetConstantTypeBlobIndex (TypeReference constant_type) + { + return GetBlobIndex (GetConstantTypeSignature (constant_type)); + } + + SignatureWriter GetVariablesSignature (Collection variables) + { + var signature = CreateSignatureWriter (); + signature.WriteByte (0x7); + signature.WriteCompressedUInt32 ((uint) variables.Count); + for (int i = 0; i < variables.Count; i++) + signature.WriteTypeSignature (variables [i].VariableType); + return signature; + } + + SignatureWriter GetConstantTypeSignature (TypeReference constant_type) + { + var signature = CreateSignatureWriter (); + signature.WriteByte (0x6); + signature.WriteTypeSignature (constant_type); + return signature; + } + + SignatureWriter GetFieldSignature (FieldReference field) + { + var signature = CreateSignatureWriter (); + signature.WriteByte (0x6); + signature.WriteTypeSignature (field.FieldType); + return signature; + } + + SignatureWriter GetMethodSignature (IMethodSignature method) + { + var signature = CreateSignatureWriter (); + signature.WriteMethodSignature (method); + return signature; + } + + SignatureWriter GetMemberRefSignature (MemberReference member) + { + var field = member as FieldReference; + if (field != null) + return GetFieldSignature (field); + + var method = member as MethodReference; + if (method != null) + return GetMethodSignature (method); + + throw new NotSupportedException (); + } + + SignatureWriter GetPropertySignature (PropertyDefinition property) + { + var signature = CreateSignatureWriter (); + byte calling_convention = 0x8; + if (property.HasThis) + calling_convention |= 0x20; + + uint param_count = 0; + Collection parameters = null; + + if (property.HasParameters) { + parameters = property.Parameters; + param_count = (uint) parameters.Count; + } + + signature.WriteByte (calling_convention); + signature.WriteCompressedUInt32 (param_count); + signature.WriteTypeSignature (property.PropertyType); + + if (param_count == 0) + return signature; + + for (int i = 0; i < param_count; i++) + signature.WriteTypeSignature (parameters [i].ParameterType); + + return signature; + } + + SignatureWriter GetTypeSpecSignature (TypeReference type) + { + var signature = CreateSignatureWriter (); + signature.WriteTypeSignature (type); + return signature; + } + + SignatureWriter GetConstantSignature (ElementType type, object value) + { + var signature = CreateSignatureWriter (); + + switch (type) { + case ElementType.Array: + case ElementType.SzArray: + case ElementType.Class: + case ElementType.Object: + case ElementType.None: + case ElementType.Var: + case ElementType.MVar: + signature.WriteInt32 (0); + break; + case ElementType.String: + signature.WriteConstantString ((string) value); + break; + default: + signature.WriteConstantPrimitive (value); + break; + } + + return signature; + } + + SignatureWriter GetCustomAttributeSignature (CustomAttribute attribute) + { + var signature = CreateSignatureWriter (); + if (!attribute.resolved) { + signature.WriteBytes (attribute.GetBlob ()); + return signature; + } + + signature.WriteUInt16 (0x0001); + + signature.WriteCustomAttributeConstructorArguments (attribute); + + signature.WriteCustomAttributeNamedArguments (attribute); + + return signature; + } + + SignatureWriter GetSecurityDeclarationSignature (SecurityDeclaration declaration) + { + var signature = CreateSignatureWriter (); + + if (!declaration.resolved) + signature.WriteBytes (declaration.GetBlob ()); + else if (module.Runtime < TargetRuntime.Net_2_0) + signature.WriteXmlSecurityDeclaration (declaration); + else + signature.WriteSecurityDeclaration (declaration); + + return signature; + } + + SignatureWriter GetMarshalInfoSignature (IMarshalInfoProvider owner) + { + var signature = CreateSignatureWriter (); + + signature.WriteMarshalInfo (owner.MarshalInfo); + + return signature; + } + + static Exception CreateForeignMemberException (MemberReference member) + { + return new ArgumentException (string.Format ("Member '{0}' is declared in another module and needs to be imported", member)); + } + + 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); + + var token = provider.MetadataToken; + + switch (token.TokenType) { + case TokenType.TypeDef: + case TokenType.Method: + case TokenType.Field: + case TokenType.Event: + case TokenType.Property: + return token; + case TokenType.TypeRef: + case TokenType.TypeSpec: + case TokenType.GenericParam: + return GetTypeToken ((TypeReference) provider); + case TokenType.MethodSpec: + return GetMethodSpecToken ((MethodSpecification) provider); + case TokenType.MemberRef: + return GetMemberRefToken (member); + default: + 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, + scope.import != null ? AddImportScope (scope.import) : 0, + 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); + + 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; + } + + public 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; + case CustomDebugInformationKind.EmbeddedSource: + AddEmbeddedSourceDebugInformation (provider, (EmbeddedSourceDebugInformation) custom_info); + break; + case CustomDebugInformationKind.SourceLink: + AddSourceLinkDebugInformation (provider, (SourceLinkDebugInformation) 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 AddEmbeddedSourceDebugInformation (ICustomDebugInformationProvider provider, EmbeddedSourceDebugInformation embedded_source) + { + var signature = CreateSignatureWriter (); + var content = embedded_source.content ?? Empty.Array; + if (embedded_source.compress) { + signature.WriteInt32 (content.Length); + + var decompressed_stream = new MemoryStream (content); + var content_stream = new MemoryStream (); + + using (var compress_stream = new DeflateStream (content_stream, CompressionMode.Compress, leaveOpen: true)) + decompressed_stream.CopyTo (compress_stream); + + signature.WriteBytes (content_stream.ToArray ()); + } else { + signature.WriteInt32 (0); + signature.WriteBytes (content); + } + + AddCustomDebugInformation (provider, embedded_source, signature); + } + + void AddSourceLinkDebugInformation (ICustomDebugInformationProvider provider, SourceLinkDebugInformation source_link) + { + var signature = CreateSignatureWriter (); + signature.WriteBytes (Encoding.UTF8.GetBytes (source_link.content)); + + AddCustomDebugInformation (provider, source_link, 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; + + AddCustomDebugInformations (document); + + 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 }); + for (int i = 0; i < parts.Length; i++) { + if (parts [i] == String.Empty) + signature.WriteCompressedUInt32 (0); + else + 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 { + + readonly MetadataBuilder metadata; + + public SignatureWriter (MetadataBuilder metadata) + : base (6) + { + this.metadata = metadata; + } + + public void WriteElementType (ElementType element_type) + { + WriteByte ((byte) element_type); + } + + public void WriteUTF8String (string @string) + { + if (@string == null) { + WriteByte (0xff); + return; + } + + var bytes = Encoding.UTF8.GetBytes (@string); + WriteCompressedUInt32 ((uint) bytes.Length); + WriteBytes (bytes); + } + + public void WriteMethodSignature (IMethodSignature method) + { + byte calling_convention = (byte) method.CallingConvention; + if (method.HasThis) + calling_convention |= 0x20; + if (method.ExplicitThis) + calling_convention |= 0x40; + + var generic_provider = method as IGenericParameterProvider; + var generic_arity = generic_provider != null && generic_provider.HasGenericParameters + ? generic_provider.GenericParameters.Count + : 0; + + if (generic_arity > 0) + calling_convention |= 0x10; + + var param_count = method.HasParameters ? method.Parameters.Count : 0; + + WriteByte (calling_convention); + + if (generic_arity > 0) + WriteCompressedUInt32 ((uint) generic_arity); + + WriteCompressedUInt32 ((uint) param_count); + WriteTypeSignature (method.ReturnType); + + if (param_count == 0) + return; + + var parameters = method.Parameters; + + for (int i = 0; i < param_count; i++) + WriteTypeSignature (parameters [i].ParameterType); + } + + 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) + throw new ArgumentNullException (); + + var etype = type.etype; + + switch (etype) { + case ElementType.MVar: + case ElementType.Var: { + var generic_parameter = (GenericParameter) type; + + WriteElementType (etype); + var position = generic_parameter.Position; + if (position == -1) + throw new NotSupportedException (); + + WriteCompressedUInt32 ((uint) position); + break; + } + + case ElementType.GenericInst: { + var generic_instance = (GenericInstanceType) type; + WriteElementType (ElementType.GenericInst); + WriteElementType (generic_instance.IsValueType ? ElementType.ValueType : ElementType.Class); + WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (generic_instance.ElementType)); + + WriteGenericInstanceSignature (generic_instance); + break; + } + + case ElementType.Ptr: + case ElementType.ByRef: + case ElementType.Pinned: + case ElementType.Sentinel: { + var type_spec = (TypeSpecification) type; + WriteElementType (etype); + WriteTypeSignature (type_spec.ElementType); + break; + } + + case ElementType.FnPtr: { + var fptr = (FunctionPointerType) type; + WriteElementType (ElementType.FnPtr); + WriteMethodSignature (fptr); + break; + } + + case ElementType.CModOpt: + case ElementType.CModReqD: { + var modifier = (IModifierType) type; + WriteModifierSignature (etype, modifier); + break; + } + + case ElementType.Array: { + var array = (ArrayType) type; + if (!array.IsVector) { + WriteArrayTypeSignature (array); + break; + } + + WriteElementType (ElementType.SzArray); + WriteTypeSignature (array.ElementType); + break; + } + + case ElementType.None: { + WriteElementType (type.IsValueType ? ElementType.ValueType : ElementType.Class); + WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type)); + break; + } + + default: + if (!TryWriteElementType (type)) + throw new NotSupportedException (); + + break; + + } + } + + void WriteArrayTypeSignature (ArrayType array) + { + WriteElementType (ElementType.Array); + WriteTypeSignature (array.ElementType); + + var dimensions = array.Dimensions; + var rank = dimensions.Count; + + WriteCompressedUInt32 ((uint) rank); + + var sized = 0; + var lbounds = 0; + + for (int i = 0; i < rank; i++) { + var dimension = dimensions [i]; + + if (dimension.UpperBound.HasValue) { + sized++; + lbounds++; + } else if (dimension.LowerBound.HasValue) + lbounds++; + } + + var sizes = new int [sized]; + var low_bounds = new int [lbounds]; + + for (int i = 0; i < lbounds; i++) { + var dimension = dimensions [i]; + low_bounds [i] = dimension.LowerBound.GetValueOrDefault (); + if (dimension.UpperBound.HasValue) + sizes [i] = dimension.UpperBound.Value - low_bounds [i] + 1; + } + + WriteCompressedUInt32 ((uint) sized); + for (int i = 0; i < sized; i++) + WriteCompressedUInt32 ((uint) sizes [i]); + + WriteCompressedUInt32 ((uint) lbounds); + for (int i = 0; i < lbounds; i++) + WriteCompressedInt32 (low_bounds [i]); + } + + public void WriteGenericInstanceSignature (IGenericInstance instance) + { + var generic_arguments = instance.GenericArguments; + var arity = generic_arguments.Count; + + WriteCompressedUInt32 ((uint) arity); + for (int i = 0; i < arity; i++) + WriteTypeSignature (generic_arguments [i]); + } + + void WriteModifierSignature (ElementType element_type, IModifierType type) + { + WriteElementType (element_type); + WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type.ModifierType)); + WriteTypeSignature (type.ElementType); + } + + bool TryWriteElementType (TypeReference type) + { + var element = type.etype; + + if (element == ElementType.None) + return false; + + WriteElementType (element); + return true; + } + + public void WriteConstantString (string value) + { + if (value != null) + WriteBytes (Encoding.Unicode.GetBytes (value)); + else + WriteByte (0xff); + } + + public void WriteConstantPrimitive (object value) + { + WritePrimitiveValue (value); + } + + public void WriteCustomAttributeConstructorArguments (CustomAttribute attribute) + { + if (!attribute.HasConstructorArguments) + return; + + var arguments = attribute.ConstructorArguments; + var parameters = attribute.Constructor.Parameters; + + if (parameters.Count != arguments.Count) + throw new InvalidOperationException (); + + for (int i = 0; i < arguments.Count; i++) + WriteCustomAttributeFixedArgument (parameters [i].ParameterType, arguments [i]); + } + + void WriteCustomAttributeFixedArgument (TypeReference type, CustomAttributeArgument argument) + { + if (type.IsArray) { + WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument); + return; + } + + WriteCustomAttributeElement (type, argument); + } + + void WriteCustomAttributeFixedArrayArgument (ArrayType type, CustomAttributeArgument argument) + { + var values = argument.Value as CustomAttributeArgument []; + + if (values == null) { + WriteUInt32 (0xffffffff); + return; + } + + WriteInt32 (values.Length); + + if (values.Length == 0) + return; + + var element_type = type.ElementType; + + for (int i = 0; i < values.Length; i++) + WriteCustomAttributeElement (element_type, values [i]); + } + + void WriteCustomAttributeElement (TypeReference type, CustomAttributeArgument argument) + { + if (type.IsArray) { + WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument); + return; + } + + if (type.etype == ElementType.Object) { + argument = (CustomAttributeArgument) argument.Value; + type = argument.Type; + + WriteCustomAttributeFieldOrPropType (type); + WriteCustomAttributeElement (type, argument); + return; + } + + WriteCustomAttributeValue (type, argument.Value); + } + + void WriteCustomAttributeValue (TypeReference type, object value) + { + var etype = type.etype; + + switch (etype) { + case ElementType.String: + var @string = (string) value; + if (@string == null) + WriteByte (0xff); + else + WriteUTF8String (@string); + break; + case ElementType.None: + if (type.IsTypeOf ("System", "Type")) + WriteTypeReference ((TypeReference) value); + else + WriteCustomAttributeEnumValue (type, value); + break; + default: + WritePrimitiveValue (value); + break; + } + } + + void WritePrimitiveValue (object value) + { + if (value == null) + throw new ArgumentNullException (); + + switch (value.GetType ().GetTypeCode ()) { + case TypeCode.Boolean: + WriteByte ((byte) (((bool) value) ? 1 : 0)); + break; + case TypeCode.Byte: + WriteByte ((byte) value); + break; + case TypeCode.SByte: + WriteSByte ((sbyte) value); + break; + case TypeCode.Int16: + WriteInt16 ((short) value); + break; + case TypeCode.UInt16: + WriteUInt16 ((ushort) value); + break; + case TypeCode.Char: + WriteInt16 ((short) (char) value); + break; + case TypeCode.Int32: + WriteInt32 ((int) value); + break; + case TypeCode.UInt32: + WriteUInt32 ((uint) value); + break; + case TypeCode.Single: + WriteSingle ((float) value); + break; + case TypeCode.Int64: + WriteInt64 ((long) value); + break; + case TypeCode.UInt64: + WriteUInt64 ((ulong) value); + break; + case TypeCode.Double: + WriteDouble ((double) value); + break; + default: + throw new NotSupportedException (value.GetType ().FullName); + } + } + + void WriteCustomAttributeEnumValue (TypeReference enum_type, object value) + { + var type = enum_type.CheckedResolve (); + if (!type.IsEnum) + throw new ArgumentException (); + + WriteCustomAttributeValue (type.GetEnumUnderlyingType (), value); + } + + void WriteCustomAttributeFieldOrPropType (TypeReference type) + { + if (type.IsArray) { + var array = (ArrayType) type; + WriteElementType (ElementType.SzArray); + WriteCustomAttributeFieldOrPropType (array.ElementType); + return; + } + + var etype = type.etype; + + switch (etype) { + case ElementType.Object: + WriteElementType (ElementType.Boxed); + return; + case ElementType.None: + if (type.IsTypeOf ("System", "Type")) + WriteElementType (ElementType.Type); + else { + WriteElementType (ElementType.Enum); + WriteTypeReference (type); + } + return; + default: + WriteElementType (etype); + return; + } + } + + public void WriteCustomAttributeNamedArguments (CustomAttribute attribute) + { + var count = GetNamedArgumentCount (attribute); + + WriteUInt16 ((ushort) count); + + if (count == 0) + return; + + WriteICustomAttributeNamedArguments (attribute); + } + + static int GetNamedArgumentCount (ICustomAttribute attribute) + { + int count = 0; + + if (attribute.HasFields) + count += attribute.Fields.Count; + + if (attribute.HasProperties) + count += attribute.Properties.Count; + + return count; + } + + void WriteICustomAttributeNamedArguments (ICustomAttribute attribute) + { + if (attribute.HasFields) + WriteCustomAttributeNamedArguments (0x53, attribute.Fields); + + if (attribute.HasProperties) + WriteCustomAttributeNamedArguments (0x54, attribute.Properties); + } + + void WriteCustomAttributeNamedArguments (byte kind, Collection named_arguments) + { + for (int i = 0; i < named_arguments.Count; i++) + WriteCustomAttributeNamedArgument (kind, named_arguments [i]); + } + + void WriteCustomAttributeNamedArgument (byte kind, CustomAttributeNamedArgument named_argument) + { + var argument = named_argument.Argument; + + WriteByte (kind); + WriteCustomAttributeFieldOrPropType (argument.Type); + WriteUTF8String (named_argument.Name); + WriteCustomAttributeFixedArgument (argument.Type, argument); + } + + void WriteSecurityAttribute (SecurityAttribute attribute) + { + WriteTypeReference (attribute.AttributeType); + + var count = GetNamedArgumentCount (attribute); + + if (count == 0) { + WriteCompressedUInt32 (1); // length + WriteCompressedUInt32 (0); // count + return; + } + + var buffer = new SignatureWriter (metadata); + buffer.WriteCompressedUInt32 ((uint) count); + buffer.WriteICustomAttributeNamedArguments (attribute); + + WriteCompressedUInt32 ((uint) buffer.length); + WriteBytes (buffer); + } + + public void WriteSecurityDeclaration (SecurityDeclaration declaration) + { + WriteByte ((byte) '.'); + + var attributes = declaration.security_attributes; + if (attributes == null) + throw new NotSupportedException (); + + WriteCompressedUInt32 ((uint) attributes.Count); + + for (int i = 0; i < attributes.Count; i++) + WriteSecurityAttribute (attributes [i]); + } + + public void WriteXmlSecurityDeclaration (SecurityDeclaration declaration) + { + var xml = GetXmlSecurityDeclaration (declaration); + if (xml == null) + throw new NotSupportedException (); + + WriteBytes (Encoding.Unicode.GetBytes (xml)); + } + + static string GetXmlSecurityDeclaration (SecurityDeclaration declaration) + { + if (declaration.security_attributes == null || declaration.security_attributes.Count != 1) + return null; + + var attribute = declaration.security_attributes [0]; + + if (!attribute.AttributeType.IsTypeOf ("System.Security.Permissions", "PermissionSetAttribute")) + return null; + + if (attribute.properties == null || attribute.properties.Count != 1) + return null; + + var property = attribute.properties [0]; + if (property.Name != "XML") + return null; + + return (string) property.Argument.Value; + } + + void WriteTypeReference (TypeReference type) + { + WriteUTF8String (TypeParser.ToParseable (type)); + } + + public void WriteMarshalInfo (MarshalInfo marshal_info) + { + WriteNativeType (marshal_info.native); + + switch (marshal_info.native) { + case NativeType.Array: { + var array = (ArrayMarshalInfo) marshal_info; + if (array.element_type != NativeType.None) + WriteNativeType (array.element_type); + if (array.size_parameter_index > -1) + WriteCompressedUInt32 ((uint) array.size_parameter_index); + if (array.size > -1) + WriteCompressedUInt32 ((uint) array.size); + if (array.size_parameter_multiplier > -1) + WriteCompressedUInt32 ((uint) array.size_parameter_multiplier); + return; + } + case NativeType.SafeArray: { + var array = (SafeArrayMarshalInfo) marshal_info; + if (array.element_type != VariantType.None) + WriteVariantType (array.element_type); + return; + } + case NativeType.FixedArray: { + var array = (FixedArrayMarshalInfo) marshal_info; + if (array.size > -1) + WriteCompressedUInt32 ((uint) array.size); + if (array.element_type != NativeType.None) + WriteNativeType (array.element_type); + return; + } + case NativeType.FixedSysString: + var sys_string = (FixedSysStringMarshalInfo) marshal_info; + if (sys_string.size > -1) + WriteCompressedUInt32 ((uint) sys_string.size); + return; + case NativeType.CustomMarshaler: + var marshaler = (CustomMarshalInfo) marshal_info; + WriteUTF8String (marshaler.guid != Guid.Empty ? marshaler.guid.ToString () : string.Empty); + WriteUTF8String (marshaler.unmanaged_type); + WriteTypeReference (marshaler.managed_type); + WriteUTF8String (marshaler.cookie); + return; + } + } + + void WriteNativeType (NativeType native) + { + WriteByte ((byte) native); + } + + 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.20/Mono.Cecil/BaseAssemblyResolver.cs b/Mono.Cecil.20/Mono.Cecil/BaseAssemblyResolver.cs new file mode 100644 index 00000000..ade0102e --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/BaseAssemblyResolver.cs @@ -0,0 +1,356 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public delegate AssemblyDefinition AssemblyResolveEventHandler (object sender, AssemblyNameReference reference); + + public sealed class AssemblyResolveEventArgs : EventArgs { + + readonly AssemblyNameReference reference; + + public AssemblyNameReference AssemblyReference { + get { return reference; } + } + + public AssemblyResolveEventArgs (AssemblyNameReference reference) + { + this.reference = reference; + } + } + +#if !NET_CORE + [Serializable] +#endif + public sealed class AssemblyResolutionException : FileNotFoundException { + + readonly AssemblyNameReference reference; + + public AssemblyNameReference AssemblyReference { + get { return reference; } + } + + public AssemblyResolutionException (AssemblyNameReference reference) + : this (reference, null) + { + } + + public AssemblyResolutionException (AssemblyNameReference reference, Exception innerException) + : base (string.Format ("Failed to resolve assembly: '{0}'", reference), innerException) + { + this.reference = reference; + } + +#if !NET_CORE + AssemblyResolutionException ( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) + : base (info, context) + { + } +#endif + } + +#if !NET_CORE + public abstract class BaseAssemblyResolver : IAssemblyResolver { + + static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null; + + readonly Collection directories; + + Collection gac_paths; + + public void AddSearchDirectory (string directory) + { + directories.Add (directory); + } + + public void RemoveSearchDirectory (string directory) + { + directories.Remove (directory); + } + + public string [] GetSearchDirectories () + { + var directories = new string [this.directories.size]; + Array.Copy (this.directories.items, directories, directories.Length); + return directories; + } + + public event AssemblyResolveEventHandler ResolveFailure; + + protected BaseAssemblyResolver () + { + directories = new Collection (2) { ".", "bin" }; + } + + AssemblyDefinition GetAssembly (string file, ReaderParameters parameters) + { + if (parameters.AssemblyResolver == null) + parameters.AssemblyResolver = this; + + return ModuleDefinition.ReadModule (file, parameters).Assembly; + } + + public virtual AssemblyDefinition Resolve (AssemblyNameReference name) + { + return Resolve (name, new ReaderParameters ()); + } + + public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters) + { + Mixin.CheckName (name); + Mixin.CheckParameters (parameters); + + var assembly = SearchDirectory (name, directories, parameters); + if (assembly != null) + return assembly; + + if (name.IsRetargetable) { + // if the reference is retargetable, zero it + name = new AssemblyNameReference (name.Name, Mixin.ZeroVersion) { + PublicKeyToken = Empty.Array, + }; + } + + var framework_dir = Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName); + var framework_dirs = on_mono + ? new [] { framework_dir, Path.Combine (framework_dir, "Facades") } + : new [] { framework_dir }; + + if (IsZero (name.Version)) { + assembly = SearchDirectory (name, framework_dirs, parameters); + if (assembly != null) + return assembly; + } + + if (name.Name == "mscorlib") { + assembly = GetCorlib (name, parameters); + if (assembly != null) + return assembly; + } + + assembly = GetAssemblyInGac (name, parameters); + if (assembly != null) + return assembly; + + assembly = SearchDirectory (name, framework_dirs, parameters); + if (assembly != null) + return assembly; + + if (ResolveFailure != null) { + assembly = ResolveFailure (this, name); + if (assembly != null) + return assembly; + } + + throw new AssemblyResolutionException (name); + } + + AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable directories, ReaderParameters parameters) + { + var extensions = name.IsWindowsRuntime ? new [] { ".winmd", ".dll" } : new [] { ".exe", ".dll" }; + foreach (var directory in directories) { + foreach (var extension in extensions) { + string file = Path.Combine (directory, name.Name + extension); + if (!File.Exists (file)) + continue; + try { + return GetAssembly (file, parameters); + } catch (System.BadImageFormatException) { + continue; + } + } + } + + return null; + } + + static bool IsZero (Version version) + { + return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0; + } + + AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters parameters) + { + var version = reference.Version; + var corlib = typeof (object).Assembly.GetName (); + + if (corlib.Version == version || IsZero (version)) + return GetAssembly (typeof (object).Module.FullyQualifiedName, parameters); + + var path = Directory.GetParent ( + Directory.GetParent ( + typeof (object).Module.FullyQualifiedName).FullName + ).FullName; + + if (on_mono) { + if (version.Major == 1) + path = Path.Combine (path, "1.0"); + else if (version.Major == 2) { + if (version.MajorRevision == 5) + path = Path.Combine (path, "2.1"); + else + path = Path.Combine (path, "2.0"); + } else if (version.Major == 4) + path = Path.Combine (path, "4.0"); + else + throw new NotSupportedException ("Version not supported: " + version); + } else { + switch (version.Major) { + case 1: + if (version.MajorRevision == 3300) + path = Path.Combine (path, "v1.0.3705"); + else + path = Path.Combine (path, "v1.0.5000.0"); + break; + case 2: + path = Path.Combine (path, "v2.0.50727"); + break; + case 4: + path = Path.Combine (path, "v4.0.30319"); + break; + default: + throw new NotSupportedException ("Version not supported: " + version); + } + } + + var file = Path.Combine (path, "mscorlib.dll"); + if (File.Exists (file)) + return GetAssembly (file, parameters); + + return null; + } + + static Collection GetGacPaths () + { + if (on_mono) + return GetDefaultMonoGacPaths (); + + var paths = new Collection (2); + var windir = Environment.GetEnvironmentVariable ("WINDIR"); + if (windir == null) + return paths; + + paths.Add (Path.Combine (windir, "assembly")); + paths.Add (Path.Combine (windir, Path.Combine ("Microsoft.NET", "assembly"))); + return paths; + } + + static Collection GetDefaultMonoGacPaths () + { + var paths = new Collection (1); + var gac = GetCurrentMonoGac (); + if (gac != null) + paths.Add (gac); + + var gac_paths_env = Environment.GetEnvironmentVariable ("MONO_GAC_PREFIX"); + if (string.IsNullOrEmpty (gac_paths_env)) + return paths; + + var prefixes = gac_paths_env.Split (Path.PathSeparator); + foreach (var prefix in prefixes) { + if (string.IsNullOrEmpty (prefix)) + continue; + + var gac_path = Path.Combine (Path.Combine (Path.Combine (prefix, "lib"), "mono"), "gac"); + if (Directory.Exists (gac_path) && !paths.Contains (gac)) + paths.Add (gac_path); + } + + return paths; + } + + static string GetCurrentMonoGac () + { + return Path.Combine ( + Directory.GetParent ( + Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName)).FullName, + "gac"); + } + + AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference, ReaderParameters parameters) + { + if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0) + return null; + + if (gac_paths == null) + gac_paths = GetGacPaths (); + + if (on_mono) + return GetAssemblyInMonoGac (reference, parameters); + + return GetAssemblyInNetGac (reference, parameters); + } + + AssemblyDefinition GetAssemblyInMonoGac (AssemblyNameReference reference, ReaderParameters parameters) + { + for (int i = 0; i < gac_paths.Count; i++) { + var gac_path = gac_paths [i]; + var file = GetAssemblyFile (reference, string.Empty, gac_path); + if (File.Exists (file)) + return GetAssembly (file, parameters); + } + + return null; + } + + AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderParameters parameters) + { + var gacs = new [] { "GAC_MSIL", "GAC_32", "GAC_64", "GAC" }; + var prefixes = new [] { string.Empty, "v4.0_" }; + + for (int i = 0; i < 2; i++) { + for (int j = 0; j < gacs.Length; j++) { + var gac = Path.Combine (gac_paths [i], gacs [j]); + var file = GetAssemblyFile (reference, prefixes [i], gac); + if (Directory.Exists (gac) && File.Exists (file)) + return GetAssembly (file, parameters); + } + } + + return null; + } + + static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac) + { + var gac_folder = new StringBuilder () + .Append (prefix) + .Append (reference.Version) + .Append ("__"); + + for (int i = 0; i < reference.PublicKeyToken.Length; i++) + gac_folder.Append (reference.PublicKeyToken [i].ToString ("x2")); + + return Path.Combine ( + Path.Combine ( + Path.Combine (gac, reference.Name), gac_folder.ToString ()), + reference.Name + ".dll"); + } + + public void Dispose () + { + Dispose (true); + GC.SuppressFinalize (this); + } + + protected virtual void Dispose (bool disposing) + { + } + } +#endif +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/CallSite.cs b/Mono.Cecil.20/Mono.Cecil/CallSite.cs similarity index 64% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/CallSite.cs rename to Mono.Cecil.20/Mono.Cecil/CallSite.cs index 448ef2a5..ebb108f2 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/CallSite.cs +++ b/Mono.Cecil.20/Mono.Cecil/CallSite.cs @@ -1,29 +1,11 @@ // -// CallSite.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; @@ -96,7 +78,7 @@ public string FullName { get { var signature = new StringBuilder (); signature.Append (ReturnType.FullName); - Mixin.MethodSignatureFullName (this,signature); + this.MethodSignatureFullName (signature); return signature.ToString (); } } diff --git a/Mono.Cecil.20/Mono.Cecil/Consts.cs b/Mono.Cecil.20/Mono.Cecil/Consts.cs new file mode 100644 index 00000000..3b80461c --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/Consts.cs @@ -0,0 +1,5 @@ +static class Consts +{ + public const string AssemblyName = "Mono.Cecil"; + public const string PublicKey = "00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf"; +} \ No newline at end of file diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/CustomAttribute.cs b/Mono.Cecil.20/Mono.Cecil/CustomAttribute.cs similarity index 72% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/CustomAttribute.cs rename to Mono.Cecil.20/Mono.Cecil/CustomAttribute.cs index 26a1a1c8..5e336676 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/CustomAttribute.cs +++ b/Mono.Cecil.20/Mono.Cecil/CustomAttribute.cs @@ -1,29 +1,11 @@ // -// CustomAttribute.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; @@ -86,6 +68,7 @@ public interface ICustomAttribute { public sealed class CustomAttribute : ICustomAttribute { + internal CustomAttributeValueProjection projection; readonly internal uint signature; internal bool resolved; MethodReference constructor; @@ -111,7 +94,7 @@ public bool HasConstructorArguments { get { Resolve (); - return !Mixin.IsNullOrEmpty (arguments); + return !arguments.IsNullOrEmpty (); } } @@ -127,7 +110,7 @@ public bool HasFields { get { Resolve (); - return !Mixin.IsNullOrEmpty (fields); + return !fields.IsNullOrEmpty (); } } @@ -143,7 +126,7 @@ public bool HasProperties { get { Resolve (); - return !Mixin.IsNullOrEmpty (properties); + return !properties.IsNullOrEmpty (); } } @@ -217,15 +200,4 @@ void Resolve () }); } } - - static partial class Mixin { - - public static void CheckName (string name) - { - if (name == null) - throw new ArgumentNullException ("name"); - if (name.Length == 0) - throw new ArgumentException ("Empty name"); - } - } } diff --git a/Mono.Cecil.20/Mono.Cecil/DefaultAssemblyResolver.cs b/Mono.Cecil.20/Mono.Cecil/DefaultAssemblyResolver.cs new file mode 100644 index 00000000..197aaa0e --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/DefaultAssemblyResolver.cs @@ -0,0 +1,65 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +#if !NET_CORE + +using System; +using System.Collections.Generic; + +namespace Mono.Cecil { + + public class DefaultAssemblyResolver : BaseAssemblyResolver { + + readonly IDictionary cache; + + public DefaultAssemblyResolver () + { + cache = new Dictionary (StringComparer.Ordinal); + } + + public override AssemblyDefinition Resolve (AssemblyNameReference name) + { + Mixin.CheckName (name); + + AssemblyDefinition assembly; + if (cache.TryGetValue (name.FullName, out assembly)) + return assembly; + + assembly = base.Resolve (name); + cache [name.FullName] = assembly; + + return assembly; + } + + protected void RegisterAssembly (AssemblyDefinition assembly) + { + if (assembly == null) + throw new ArgumentNullException ("assembly"); + + var name = assembly.Name.FullName; + if (cache.ContainsKey (name)) + return; + + cache [name] = assembly; + } + + protected override void Dispose (bool disposing) + { + foreach (var assembly in cache.Values) + assembly.Dispose (); + + cache.Clear (); + + base.Dispose (disposing); + } + } +} + +#endif diff --git a/Mono.Cecil.20/Mono.Cecil/EmbeddedResource.cs b/Mono.Cecil.20/Mono.Cecil/EmbeddedResource.cs new file mode 100644 index 00000000..6b5f86a1 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/EmbeddedResource.cs @@ -0,0 +1,98 @@ +// +// 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.IO; + +namespace Mono.Cecil { + + public sealed class EmbeddedResource : Resource { + + readonly MetadataReader reader; + + uint? offset; + byte [] data; + Stream stream; + + public override ResourceType ResourceType { + get { return ResourceType.Embedded; } + } + + public EmbeddedResource (string name, ManifestResourceAttributes attributes, byte [] data) : + base (name, attributes) + { + this.data = data; + } + + public EmbeddedResource (string name, ManifestResourceAttributes attributes, Stream stream) : + base (name, attributes) + { + this.stream = stream; + } + + internal EmbeddedResource (string name, ManifestResourceAttributes attributes, uint offset, MetadataReader reader) + : base (name, attributes) + { + this.offset = offset; + this.reader = reader; + } + + public Stream GetResourceStream () + { + if (stream != null) + return stream; + + if (data != null) + return new MemoryStream (data); + + if (offset.HasValue) + return new MemoryStream (reader.GetManagedResource (offset.Value)); + + throw new InvalidOperationException (); + } + + public byte [] GetResourceData () + { + if (stream != null) + return ReadStream (stream); + + if (data != null) + return data; + + if (offset.HasValue) + return reader.GetManagedResource (offset.Value); + + throw new InvalidOperationException (); + } + + static byte [] ReadStream (Stream stream) + { + int read; + + if (stream.CanSeek) { + var length = (int) stream.Length; + var data = new byte [length]; + int offset = 0; + + while ((read = stream.Read (data, offset, length - offset)) > 0) + offset += read; + + return data; + } + + var buffer = new byte [1024 * 8]; + var memory = new MemoryStream (); + while ((read = stream.Read (buffer, 0, buffer.Length)) > 0) + memory.Write (buffer, 0, read); + + return memory.ToArray (); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/EventAttributes.cs b/Mono.Cecil.20/Mono.Cecil/EventAttributes.cs new file mode 100644 index 00000000..9f823fd1 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/EventAttributes.cs @@ -0,0 +1,21 @@ +// +// 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; + +namespace Mono.Cecil { + + [Flags] + public enum EventAttributes : ushort { + None = 0x0000, + SpecialName = 0x0200, // Event is special + RTSpecialName = 0x0400 // CLI provides 'special' behavior, depending upon the name of the event + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventDefinition.cs b/Mono.Cecil.20/Mono.Cecil/EventDefinition.cs similarity index 60% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/EventDefinition.cs rename to Mono.Cecil.20/Mono.Cecil/EventDefinition.cs index 88bfa982..33bc341a 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventDefinition.cs +++ b/Mono.Cecil.20/Mono.Cecil/EventDefinition.cs @@ -1,29 +1,11 @@ // -// EventDefinition.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using Mono.Collections.Generic; @@ -85,7 +67,7 @@ public bool HasOtherMethods { return other_methods.Count > 0; InitializeMethods (); - return !Mixin.IsNullOrEmpty (other_methods); + return !other_methods.IsNullOrEmpty (); } } @@ -108,24 +90,24 @@ public bool HasCustomAttributes { if (custom_attributes != null) return custom_attributes.Count > 0; - return Mixin.GetHasCustomAttributes(this, Module); + return this.GetHasCustomAttributes (Module); } } public Collection CustomAttributes { - get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } } #region EventAttributes public bool IsSpecialName { - get { return Mixin.GetAttributes(attributes,(ushort) EventAttributes.SpecialName); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) EventAttributes.SpecialName, value); } + get { return attributes.GetAttributes ((ushort) EventAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((ushort) EventAttributes.SpecialName, value); } } public bool IsRuntimeSpecialName { - get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.RTSpecialName); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.RTSpecialName, value); } + get { return attributes.GetAttributes ((ushort) EventAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((ushort) EventAttributes.RTSpecialName, value); } } #endregion @@ -149,13 +131,16 @@ public EventDefinition (string name, EventAttributes attributes, TypeReference e void InitializeMethods () { var module = this.Module; + if (module == null) + return; + lock (module.SyncRoot) { if (add_method != null || invoke_method != null || remove_method != null) return; - if (!Mixin.HasImage(module)) + if (!module.HasImage ()) return; module.Read (this, (@event, reader) => reader.ReadMethods (@event)); diff --git a/Mono.Cecil.20/Mono.Cecil/EventReference.cs b/Mono.Cecil.20/Mono.Cecil/EventReference.cs new file mode 100644 index 00000000..d4df72b4 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/EventReference.cs @@ -0,0 +1,42 @@ +// +// 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; + +namespace Mono.Cecil { + + public abstract class EventReference : MemberReference { + + TypeReference event_type; + + public TypeReference EventType { + get { return event_type; } + set { event_type = value; } + } + + public override string FullName { + get { return event_type.FullName + " " + MemberFullName (); } + } + + protected EventReference (string name, TypeReference eventType) + : base (name) + { + Mixin.CheckType (eventType, Mixin.Argument.eventType); + event_type = eventType; + } + + protected override IMemberDefinition ResolveDefinition () + { + return this.Resolve (); + } + + public new abstract EventDefinition Resolve (); + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/ExportedType.cs b/Mono.Cecil.20/Mono.Cecil/ExportedType.cs new file mode 100644 index 00000000..8238a0c6 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/ExportedType.cs @@ -0,0 +1,240 @@ +// +// 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; + +namespace Mono.Cecil { + + public sealed class ExportedType : IMetadataTokenProvider { + + string @namespace; + string name; + uint attributes; + IMetadataScope scope; + ModuleDefinition module; + int identifier; + ExportedType declaring_type; + internal MetadataToken token; + + public string Namespace { + get { return @namespace; } + set { @namespace = value; } + } + + public string Name { + get { return name; } + set { name = value; } + } + + public TypeAttributes Attributes { + get { return (TypeAttributes) attributes; } + set { attributes = (uint) value; } + } + + public IMetadataScope Scope { + get { + if (declaring_type != null) + return declaring_type.Scope; + + return scope; + } + set { + if (declaring_type != null) { + declaring_type.Scope = value; + return; + } + + scope = value; + } + } + + public ExportedType DeclaringType { + get { return declaring_type; } + set { declaring_type = value; } + } + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + public int Identifier { + get { return identifier; } + set { identifier = value; } + } + + #region TypeAttributes + + public bool IsNotPublic { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); } + } + + public bool IsPublic { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); } + } + + public bool IsNestedPublic { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); } + } + + public bool IsNestedPrivate { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); } + } + + public bool IsNestedFamily { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); } + } + + public bool IsNestedAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); } + } + + public bool IsNestedFamilyAndAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); } + } + + public bool IsNestedFamilyOrAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); } + } + + public bool IsAutoLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); } + } + + public bool IsSequentialLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); } + } + + public bool IsExplicitLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); } + } + + public bool IsClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); } + } + + public bool IsInterface { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); } + } + + public bool IsAbstract { + get { return attributes.GetAttributes ((uint) TypeAttributes.Abstract); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Abstract, value); } + } + + public bool IsSealed { + get { return attributes.GetAttributes ((uint) TypeAttributes.Sealed); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Sealed, value); } + } + + public bool IsSpecialName { + get { return attributes.GetAttributes ((uint) TypeAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.SpecialName, value); } + } + + public bool IsImport { + get { return attributes.GetAttributes ((uint) TypeAttributes.Import); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Import, value); } + } + + public bool IsSerializable { + get { return attributes.GetAttributes ((uint) TypeAttributes.Serializable); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Serializable, value); } + } + + public bool IsAnsiClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); } + } + + public bool IsUnicodeClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); } + } + + public bool IsAutoClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); } + } + + public bool IsBeforeFieldInit { + get { return attributes.GetAttributes ((uint) TypeAttributes.BeforeFieldInit); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.BeforeFieldInit, value); } + } + + public bool IsRuntimeSpecialName { + get { return attributes.GetAttributes ((uint) TypeAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.RTSpecialName, value); } + } + + public bool HasSecurity { + get { return attributes.GetAttributes ((uint) TypeAttributes.HasSecurity); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.HasSecurity, value); } + } + + #endregion + + public bool IsForwarder { + get { return attributes.GetAttributes ((uint) TypeAttributes.Forwarder); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Forwarder, value); } + } + + public string FullName { + get { + var fullname = string.IsNullOrEmpty (@namespace) + ? name + : @namespace + '.' + name; + + if (declaring_type != null) + return declaring_type.FullName + "/" + fullname; + + return fullname; + } + } + + public ExportedType (string @namespace, string name, ModuleDefinition module, IMetadataScope scope) + { + this.@namespace = @namespace; + this.name = name; + this.scope = scope; + this.module = module; + } + + public override string ToString () + { + return FullName; + } + + public TypeDefinition Resolve () + { + return module.Resolve (CreateReference ()); + } + + internal TypeReference CreateReference () + { + return new TypeReference (@namespace, name, module, scope) { + DeclaringType = declaring_type != null ? declaring_type.CreateReference () : null, + }; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldAttributes.cs b/Mono.Cecil.20/Mono.Cecil/FieldAttributes.cs similarity index 55% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldAttributes.cs rename to Mono.Cecil.20/Mono.Cecil/FieldAttributes.cs index dd6bf361..7d5bb544 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldAttributes.cs +++ b/Mono.Cecil.20/Mono.Cecil/FieldAttributes.cs @@ -1,29 +1,11 @@ // -// FieldAttributes.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; diff --git a/Mono.Cecil.20/Mono.Cecil/FieldDefinition.cs b/Mono.Cecil.20/Mono.Cecil/FieldDefinition.cs new file mode 100644 index 00000000..593b77e5 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/FieldDefinition.cs @@ -0,0 +1,267 @@ +// +// 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 Mono.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class FieldDefinition : FieldReference, IMemberDefinition, IConstantProvider, IMarshalInfoProvider { + + ushort attributes; + Collection custom_attributes; + + int offset = Mixin.NotResolvedMarker; + + internal int rva = Mixin.NotResolvedMarker; + byte [] initial_value; + + object constant = Mixin.NotResolved; + + MarshalInfo marshal_info; + + void ResolveLayout () + { + if (offset != Mixin.NotResolvedMarker) + return; + + if (!HasImage) { + offset = Mixin.NoDataMarker; + return; + } + + offset = Module.Read (this, (field, reader) => reader.ReadFieldLayout (field)); + } + + public bool HasLayoutInfo { + get { + if (offset >= 0) + return true; + + ResolveLayout (); + + return offset >= 0; + } + } + + public int Offset { + get { + if (offset >= 0) + return offset; + + ResolveLayout (); + + return offset >= 0 ? offset : -1; + } + set { offset = value; } + } + + internal new FieldDefinitionProjection WindowsRuntimeProjection { + get { return (FieldDefinitionProjection) projection; } + set { projection = value; } + } + + void ResolveRVA () + { + if (rva != Mixin.NotResolvedMarker) + return; + + if (!HasImage) + return; + + rva = Module.Read (this, (field, reader) => reader.ReadFieldRVA (field)); + } + + public int RVA { + get { + if (rva > 0) + return rva; + + ResolveRVA (); + + return rva > 0 ? rva : 0; + } + } + + public byte [] InitialValue { + get { + if (initial_value != null) + return initial_value; + + ResolveRVA (); + + if (initial_value == null) + initial_value = Empty.Array; + + return initial_value; + } + set { + initial_value = value; + rva = 0; + } + } + + public FieldAttributes Attributes { + get { return (FieldAttributes) attributes; } + set { + if (IsWindowsRuntimeProjection && (ushort) value != attributes) + throw new InvalidOperationException (); + + attributes = (ushort) value; + } + } + + public bool HasConstant { + get { + this.ResolveConstant (ref constant, Module); + + return constant != Mixin.NoValue; + } + set { if (!value) constant = Mixin.NoValue; } + } + + public object Constant { + get { return HasConstant ? constant : null; } + set { constant = value; } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return this.GetHasCustomAttributes (Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } + } + + public bool HasMarshalInfo { + get { + if (marshal_info != null) + return true; + + return this.GetHasMarshalInfo (Module); + } + } + + public MarshalInfo MarshalInfo { + get { return marshal_info ?? (this.GetMarshalInfo (ref marshal_info, Module)); } + set { marshal_info = value; } + } + + #region FieldAttributes + + public bool IsCompilerControlled { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled, value); } + } + + public bool IsPrivate { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private, value); } + } + + public bool IsFamilyAndAssembly { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem, value); } + } + + public bool IsAssembly { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly, value); } + } + + public bool IsFamily { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family, value); } + } + + public bool IsFamilyOrAssembly { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem, value); } + } + + public bool IsPublic { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public, value); } + } + + public bool IsStatic { + get { return attributes.GetAttributes ((ushort) FieldAttributes.Static); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.Static, value); } + } + + public bool IsInitOnly { + get { return attributes.GetAttributes ((ushort) FieldAttributes.InitOnly); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.InitOnly, value); } + } + + public bool IsLiteral { + get { return attributes.GetAttributes ((ushort) FieldAttributes.Literal); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.Literal, value); } + } + + public bool IsNotSerialized { + get { return attributes.GetAttributes ((ushort) FieldAttributes.NotSerialized); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.NotSerialized, value); } + } + + public bool IsSpecialName { + get { return attributes.GetAttributes ((ushort) FieldAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.SpecialName, value); } + } + + public bool IsPInvokeImpl { + get { return attributes.GetAttributes ((ushort) FieldAttributes.PInvokeImpl); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.PInvokeImpl, value); } + } + + public bool IsRuntimeSpecialName { + get { return attributes.GetAttributes ((ushort) FieldAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.RTSpecialName, value); } + } + + public bool HasDefault { + get { return attributes.GetAttributes ((ushort) FieldAttributes.HasDefault); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.HasDefault, value); } + } + + #endregion + + public override bool IsDefinition { + get { return true; } + } + + public new TypeDefinition DeclaringType { + get { return (TypeDefinition) base.DeclaringType; } + set { base.DeclaringType = value; } + } + + public FieldDefinition (string name, FieldAttributes attributes, TypeReference fieldType) + : base (name, fieldType) + { + this.attributes = (ushort) attributes; + } + + public override FieldDefinition Resolve () + { + return this; + } + } + + static partial class Mixin { + + public const int NotResolvedMarker = -2; + public const int NoDataMarker = -1; + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/FieldReference.cs b/Mono.Cecil.20/Mono.Cecil/FieldReference.cs new file mode 100644 index 00000000..944c2259 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/FieldReference.cs @@ -0,0 +1,68 @@ +// +// 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; + +namespace Mono.Cecil { + + public class FieldReference : MemberReference { + + TypeReference field_type; + + public TypeReference FieldType { + get { return field_type; } + set { field_type = value; } + } + + public override string FullName { + get { return field_type.FullName + " " + MemberFullName (); } + } + + public override bool ContainsGenericParameter { + get { return field_type.ContainsGenericParameter || base.ContainsGenericParameter; } + } + + internal FieldReference () + { + this.token = new MetadataToken (TokenType.MemberRef); + } + + public FieldReference (string name, TypeReference fieldType) + : base (name) + { + Mixin.CheckType (fieldType, Mixin.Argument.fieldType); + + this.field_type = fieldType; + this.token = new MetadataToken (TokenType.MemberRef); + } + + public FieldReference (string name, TypeReference fieldType, TypeReference declaringType) + : this (name, fieldType) + { + Mixin.CheckType (declaringType, Mixin.Argument.declaringType); + + this.DeclaringType = declaringType; + } + + protected override IMemberDefinition ResolveDefinition () + { + return this.Resolve (); + } + + public new virtual FieldDefinition Resolve () + { + var module = this.Module; + if (module == null) + throw new NotSupportedException (); + + return module.Resolve (this); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/FileAttributes.cs b/Mono.Cecil.20/Mono.Cecil/FileAttributes.cs new file mode 100644 index 00000000..171f174b --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/FileAttributes.cs @@ -0,0 +1,17 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + enum FileAttributes : uint { + ContainsMetaData = 0x0000, // This is not a resource file + ContainsNoMetaData = 0x0001, // This is a resource file or other non-metadata-containing file + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FunctionPointerType.cs b/Mono.Cecil.20/Mono.Cecil/FunctionPointerType.cs similarity index 64% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/FunctionPointerType.cs rename to Mono.Cecil.20/Mono.Cecil/FunctionPointerType.cs index 484afdaf..0602fcbe 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FunctionPointerType.cs +++ b/Mono.Cecil.20/Mono.Cecil/FunctionPointerType.cs @@ -1,29 +1,11 @@ // -// FunctionPointerType.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; @@ -85,13 +67,14 @@ public override ModuleDefinition Module { public override IMetadataScope Scope { get { return function.ReturnType.Scope; } + set { throw new InvalidOperationException (); } } public override bool IsFunctionPointer { get { return true; } } - internal override bool ContainsGenericParameter { + public override bool ContainsGenericParameter { get { return function.ContainsGenericParameter; } } @@ -102,7 +85,7 @@ public override string FullName { signature.Append (" "); signature.Append (function.ReturnType.FullName); signature.Append (" *"); - Mixin.MethodSignatureFullName (this,signature); + this.MethodSignatureFullName (signature); return signature.ToString (); } } diff --git a/Mono.Cecil.20/Mono.Cecil/GenericInstanceMethod.cs b/Mono.Cecil.20/Mono.Cecil/GenericInstanceMethod.cs new file mode 100644 index 00000000..00de03a3 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/GenericInstanceMethod.cs @@ -0,0 +1,67 @@ +// +// 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.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class GenericInstanceMethod : MethodSpecification, IGenericInstance, IGenericContext { + + Collection arguments; + + public bool HasGenericArguments { + get { return !arguments.IsNullOrEmpty (); } + } + + public Collection GenericArguments { + get { return arguments ?? (arguments = new Collection ()); } + } + + public override bool IsGenericInstance { + get { return true; } + } + + IGenericParameterProvider IGenericContext.Method { + get { return ElementMethod; } + } + + IGenericParameterProvider IGenericContext.Type { + get { return ElementMethod.DeclaringType; } + } + + public override bool ContainsGenericParameter { + get { return this.ContainsGenericParameter () || base.ContainsGenericParameter; } + } + + public override string FullName { + get { + var signature = new StringBuilder (); + var method = this.ElementMethod; + signature.Append (method.ReturnType.FullName) + .Append (" ") + .Append (method.DeclaringType.FullName) + .Append ("::") + .Append (method.Name); + this.GenericInstanceFullName (signature); + this.MethodSignatureFullName (signature); + return signature.ToString (); + + } + } + + public GenericInstanceMethod (MethodReference method) + : base (method) + { + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/GenericInstanceType.cs b/Mono.Cecil.20/Mono.Cecil/GenericInstanceType.cs new file mode 100644 index 00000000..0e683e71 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/GenericInstanceType.cs @@ -0,0 +1,65 @@ +// +// 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.Text; + +using Mono.Collections.Generic; + +using MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public sealed class GenericInstanceType : TypeSpecification, IGenericInstance, IGenericContext { + + Collection arguments; + + public bool HasGenericArguments { + get { return !arguments.IsNullOrEmpty (); } + } + + public Collection GenericArguments { + get { return arguments ?? (arguments = new Collection ()); } + } + + public override TypeReference DeclaringType { + get { return ElementType.DeclaringType; } + set { throw new NotSupportedException (); } + } + + public override string FullName { + get { + var name = new StringBuilder (); + name.Append (base.FullName); + this.GenericInstanceFullName (name); + return name.ToString (); + } + } + + public override bool IsGenericInstance { + get { return true; } + } + + public override bool ContainsGenericParameter { + get { return this.ContainsGenericParameter () || base.ContainsGenericParameter; } + } + + IGenericParameterProvider IGenericContext.Type { + get { return ElementType; } + } + + public GenericInstanceType (TypeReference type) + : base (type) + { + base.IsValueType = type.IsValueType; + this.etype = MD.ElementType.GenericInst; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameter.cs b/Mono.Cecil.20/Mono.Cecil/GenericParameter.cs similarity index 59% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameter.cs rename to Mono.Cecil.20/Mono.Cecil/GenericParameter.cs index e92728d6..f2997da6 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameter.cs +++ b/Mono.Cecil.20/Mono.Cecil/GenericParameter.cs @@ -1,29 +1,11 @@ // -// GenericParameter.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; @@ -66,10 +48,7 @@ public bool HasConstraints { if (constraints != null) return constraints.Count > 0; - if (HasImage) - return Module.Read (this, (generic_parameter, reader) => reader.HasGenericConstraints (generic_parameter)); - - return false; + return HasImage && Module.Read (this, (generic_parameter, reader) => reader.HasGenericConstraints (generic_parameter)); } } @@ -90,12 +69,12 @@ public bool HasCustomAttributes { if (custom_attributes != null) return custom_attributes.Count > 0; - return Mixin.GetHasCustomAttributes(this, Module); + return this.GetHasCustomAttributes (Module); } } public Collection CustomAttributes { - get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } } public override IMetadataScope Scope { @@ -107,6 +86,16 @@ public override IMetadataScope Scope { ? ((MethodReference) owner).DeclaringType.Scope : ((TypeReference) owner).Scope; } + set { throw new InvalidOperationException (); } + } + + public override TypeReference DeclaringType { + get { return owner as TypeReference; } + set { throw new InvalidOperationException (); } + } + + public MethodReference DeclaringMethod { + get { return owner as MethodReference; } } public override ModuleDefinition Module { @@ -135,7 +124,7 @@ public override bool IsGenericParameter { get { return true; } } - internal override bool ContainsGenericParameter { + public override bool ContainsGenericParameter { get { return true; } } @@ -146,33 +135,33 @@ public override MetadataType MetadataType { #region GenericParameterAttributes public bool IsNonVariant { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant, value); } + get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant); } + set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant, value); } } public bool IsCovariant { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant, value); } + get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant); } + set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant, value); } } public bool IsContravariant { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant, value); } + get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant); } + set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant, value); } } public bool HasReferenceTypeConstraint { - get { return Mixin.GetAttributes(attributes,(ushort) GenericParameterAttributes.ReferenceTypeConstraint); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) GenericParameterAttributes.ReferenceTypeConstraint, value); } + get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.ReferenceTypeConstraint); } + set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.ReferenceTypeConstraint, value); } } public bool HasNotNullableValueTypeConstraint { - get { return Mixin.GetAttributes(attributes,(ushort) GenericParameterAttributes.NotNullableValueTypeConstraint); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) GenericParameterAttributes.NotNullableValueTypeConstraint, value); } + get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.NotNullableValueTypeConstraint); } + set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.NotNullableValueTypeConstraint, value); } } public bool HasDefaultConstructorConstraint { - get { return Mixin.GetAttributes(attributes,(ushort) GenericParameterAttributes.DefaultConstructorConstraint); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) GenericParameterAttributes.DefaultConstructorConstraint, value); } + get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.DefaultConstructorConstraint); } + set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.DefaultConstructorConstraint, value); } } #endregion @@ -192,18 +181,20 @@ public GenericParameter (string name, IGenericParameterProvider owner) this.owner = owner; this.type = owner.GenericParameterType; this.etype = ConvertGenericParameterType (this.type); + this.token = new MetadataToken (TokenType.GenericParam); + } - public GenericParameter (int position, GenericParameterType type, ModuleDefinition module) + internal GenericParameter (int position, GenericParameterType type, ModuleDefinition module) : base (string.Empty, string.Empty) { - if (module == null) - throw new ArgumentNullException (); + Mixin.CheckModule (module); this.position = position; this.type = type; this.etype = ConvertGenericParameterType (type); this.module = module; + this.token = new MetadataToken (TokenType.GenericParam); } static ElementType ConvertGenericParameterType (GenericParameterType type) diff --git a/Mono.Cecil.20/Mono.Cecil/GenericParameterAttributes.cs b/Mono.Cecil.20/Mono.Cecil/GenericParameterAttributes.cs new file mode 100644 index 00000000..149582cd --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/GenericParameterAttributes.cs @@ -0,0 +1,27 @@ +// +// 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; + +namespace Mono.Cecil { + + [Flags] + public enum GenericParameterAttributes : ushort { + VarianceMask = 0x0003, + NonVariant = 0x0000, + Covariant = 0x0001, + Contravariant = 0x0002, + + SpecialConstraintMask = 0x001c, + ReferenceTypeConstraint = 0x0004, + NotNullableValueTypeConstraint = 0x0008, + DefaultConstructorConstraint = 0x0010 + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/IConstantProvider.cs b/Mono.Cecil.20/Mono.Cecil/IConstantProvider.cs new file mode 100644 index 00000000..178b6651 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/IConstantProvider.cs @@ -0,0 +1,44 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public interface IConstantProvider : IMetadataTokenProvider { + + bool HasConstant { get; set; } + object Constant { get; set; } + } + + static partial class Mixin { + + internal static object NoValue = new object (); + internal static object NotResolved = new object (); + + public static void ResolveConstant ( + this IConstantProvider self, + ref object constant, + ModuleDefinition module) + { + if (module == null) { + constant = Mixin.NoValue; + return; + } + + lock (module.SyncRoot) { + if (constant != Mixin.NotResolved) + return; + if (module.HasImage ()) + constant = module.Read (self, (provider, reader) => reader.ReadConstant (provider)); + else + constant = Mixin.NoValue; + } + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/ICustomAttributeProvider.cs b/Mono.Cecil.20/Mono.Cecil/ICustomAttributeProvider.cs new file mode 100644 index 00000000..36d7ed01 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/ICustomAttributeProvider.cs @@ -0,0 +1,42 @@ +// +// 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 Mono.Collections.Generic; + +namespace Mono.Cecil { + + public interface ICustomAttributeProvider : IMetadataTokenProvider { + + Collection CustomAttributes { get; } + + bool HasCustomAttributes { get; } + } + + static partial class Mixin { + + public static bool GetHasCustomAttributes ( + this ICustomAttributeProvider self, + ModuleDefinition module) + { + return module.HasImage () && module.Read (self, (provider, reader) => reader.HasCustomAttributes (provider)); + } + + public static Collection GetCustomAttributes ( + this ICustomAttributeProvider self, + ref Collection variable, + ModuleDefinition module) + { + return module.HasImage () + ? module.Read (ref variable, self, (provider, reader) => reader.ReadCustomAttributes (provider)) + : variable = new Collection(); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/IGenericInstance.cs b/Mono.Cecil.20/Mono.Cecil/IGenericInstance.cs new file mode 100644 index 00000000..e98d8189 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/IGenericInstance.cs @@ -0,0 +1,48 @@ +// +// 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.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public interface IGenericInstance : IMetadataTokenProvider { + + bool HasGenericArguments { get; } + Collection GenericArguments { get; } + } + + static partial class Mixin { + + public static bool ContainsGenericParameter (this IGenericInstance self) + { + var arguments = self.GenericArguments; + + for (int i = 0; i < arguments.Count; i++) + if (arguments [i].ContainsGenericParameter) + return true; + + return false; + } + + public static void GenericInstanceFullName (this IGenericInstance self, StringBuilder builder) + { + builder.Append ("<"); + var arguments = self.GenericArguments; + for (int i = 0; i < arguments.Count; i++) { + if (i > 0) + builder.Append (","); + builder.Append (arguments [i].FullName); + } + builder.Append (">"); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/IGenericParameterProvider.cs b/Mono.Cecil.20/Mono.Cecil/IGenericParameterProvider.cs new file mode 100644 index 00000000..4c8dfc4d --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/IGenericParameterProvider.cs @@ -0,0 +1,56 @@ +// +// 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.Collections.Generic; + +namespace Mono.Cecil { + + public interface IGenericParameterProvider : IMetadataTokenProvider { + + bool HasGenericParameters { get; } + bool IsDefinition { get; } + ModuleDefinition Module { get; } + Collection GenericParameters { get; } + GenericParameterType GenericParameterType { get; } + } + + public enum GenericParameterType { + Type, + Method + } + + interface IGenericContext { + + bool IsDefinition { get; } + IGenericParameterProvider Type { get; } + IGenericParameterProvider Method { get; } + } + + static partial class Mixin { + + public static bool GetHasGenericParameters ( + this IGenericParameterProvider self, + ModuleDefinition module) + { + return module.HasImage () && module.Read (self, (provider, reader) => reader.HasGenericParameters (provider)); + } + + public static Collection GetGenericParameters ( + this IGenericParameterProvider self, + ref Collection collection, + ModuleDefinition module) + { + return module.HasImage () + ? module.Read (ref collection, self, (provider, reader) => reader.ReadGenericParameters (provider)) + : collection = new GenericParameterCollection (self); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/IMarshalInfoProvider.cs b/Mono.Cecil.20/Mono.Cecil/IMarshalInfoProvider.cs new file mode 100644 index 00000000..a1b9e883 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/IMarshalInfoProvider.cs @@ -0,0 +1,38 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public interface IMarshalInfoProvider : IMetadataTokenProvider { + + bool HasMarshalInfo { get; } + MarshalInfo MarshalInfo { get; set; } + } + + static partial class Mixin { + + public static bool GetHasMarshalInfo ( + this IMarshalInfoProvider self, + ModuleDefinition module) + { + return module.HasImage () && module.Read (self, (provider, reader) => reader.HasMarshalInfo (provider)); + } + + public static MarshalInfo GetMarshalInfo ( + this IMarshalInfoProvider self, + ref MarshalInfo variable, + ModuleDefinition module) + { + return module.HasImage () + ? module.Read (ref variable, self, (provider, reader) => reader.ReadMarshalInfo (provider)) + : null; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/IMemberDefinition.cs b/Mono.Cecil.20/Mono.Cecil/IMemberDefinition.cs new file mode 100644 index 00000000..ad747002 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/IMemberDefinition.cs @@ -0,0 +1,82 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public interface IMemberDefinition : ICustomAttributeProvider { + + string Name { get; set; } + string FullName { get; } + + bool IsSpecialName { get; set; } + bool IsRuntimeSpecialName { get; set; } + + TypeDefinition DeclaringType { get; set; } + } + + static partial class Mixin { + + public static bool GetAttributes (this uint self, uint attributes) + { + return (self & attributes) != 0; + } + + public static uint SetAttributes (this uint self, uint attributes, bool value) + { + if (value) + return self | attributes; + + return self & ~attributes; + } + + public static bool GetMaskedAttributes (this uint self, uint mask, uint attributes) + { + return (self & mask) == attributes; + } + + public static uint SetMaskedAttributes (this uint self, uint mask, uint attributes, bool value) + { + if (value) { + self &= ~mask; + return self | attributes; + } + + return self & ~(mask & attributes); + } + + public static bool GetAttributes (this ushort self, ushort attributes) + { + return (self & attributes) != 0; + } + + public static ushort SetAttributes (this ushort self, ushort attributes, bool value) + { + if (value) + return (ushort) (self | attributes); + + return (ushort) (self & ~attributes); + } + + public static bool GetMaskedAttributes (this ushort self, ushort mask, uint attributes) + { + return (self & mask) == attributes; + } + + public static ushort SetMaskedAttributes (this ushort self, ushort mask, uint attributes, bool value) + { + if (value) { + self = (ushort) (self & ~mask); + return (ushort) (self | attributes); + } + + return (ushort) (self & ~(mask & attributes)); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/IMetadataScope.cs b/Mono.Cecil.20/Mono.Cecil/IMetadataScope.cs new file mode 100644 index 00000000..2e56e758 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/IMetadataScope.cs @@ -0,0 +1,23 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum MetadataScopeType { + AssemblyNameReference, + ModuleReference, + ModuleDefinition, + } + + public interface IMetadataScope : IMetadataTokenProvider { + MetadataScopeType MetadataScopeType { get; } + string Name { get; set; } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/IMetadataTokenProvider.cs b/Mono.Cecil.20/Mono.Cecil/IMetadataTokenProvider.cs new file mode 100644 index 00000000..dcd678b0 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/IMetadataTokenProvider.cs @@ -0,0 +1,17 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public interface IMetadataTokenProvider { + + MetadataToken MetadataToken { get; set; } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/IMethodSignature.cs b/Mono.Cecil.20/Mono.Cecil/IMethodSignature.cs new file mode 100644 index 00000000..4d7766e4 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/IMethodSignature.cs @@ -0,0 +1,57 @@ +// +// 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.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public interface IMethodSignature : IMetadataTokenProvider { + + bool HasThis { get; set; } + bool ExplicitThis { get; set; } + MethodCallingConvention CallingConvention { get; set; } + + bool HasParameters { get; } + Collection Parameters { get; } + TypeReference ReturnType { get; set; } + MethodReturnType MethodReturnType { get; } + } + + static partial class Mixin { + + public static bool HasImplicitThis (this IMethodSignature self) + { + return self.HasThis && !self.ExplicitThis; + } + + public static void MethodSignatureFullName (this IMethodSignature self, StringBuilder builder) + { + builder.Append ("("); + + if (self.HasParameters) { + var parameters = self.Parameters; + for (int i = 0; i < parameters.Count; i++) { + var parameter = parameters [i]; + if (i > 0) + builder.Append (","); + + if (parameter.ParameterType.IsSentinel) + builder.Append ("...,"); + + builder.Append (parameter.ParameterType.FullName); + } + } + + builder.Append (")"); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/Import.cs b/Mono.Cecil.20/Mono.Cecil/Import.cs new file mode 100644 index 00000000..4bf10cc7 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/Import.cs @@ -0,0 +1,819 @@ +// +// 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 Mono.Collections.Generic; +using SR = System.Reflection; + +using Mono.Cecil.Metadata; + +namespace Mono.Cecil { + +#if !READ_ONLY + + public interface IMetadataImporterProvider { + IMetadataImporter GetMetadataImporter (ModuleDefinition module); + } + + public interface IMetadataImporter { + AssemblyNameReference ImportReference (AssemblyNameReference reference); + TypeReference ImportReference (TypeReference type, IGenericParameterProvider context); + FieldReference ImportReference (FieldReference field, IGenericParameterProvider context); + MethodReference ImportReference (MethodReference method, IGenericParameterProvider context); + } + + public interface IReflectionImporterProvider { + IReflectionImporter GetReflectionImporter (ModuleDefinition module); + } + + public interface IReflectionImporter { + AssemblyNameReference ImportReference (SR.AssemblyName reference); + TypeReference ImportReference (Type type, IGenericParameterProvider context); + FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context); + MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context); + } + + struct ImportGenericContext { + + Collection stack; + + public bool IsEmpty { get { return stack == null; } } + + public ImportGenericContext (IGenericParameterProvider provider) + { + if (provider == null) + throw new ArgumentNullException ("provider"); + + stack = null; + + Push (provider); + } + + public void Push (IGenericParameterProvider provider) + { + if (stack == null) + stack = new Collection (1) { provider }; + else + stack.Add (provider); + } + + public void Pop () + { + stack.RemoveAt (stack.Count - 1); + } + + public TypeReference MethodParameter (string method, int position) + { + for (int i = stack.Count - 1; i >= 0; i--) { + var candidate = stack [i] as MethodReference; + if (candidate == null) + continue; + + if (method != NormalizeMethodName (candidate)) + continue; + + return candidate.GenericParameters [position]; + } + + throw new InvalidOperationException (); + } + + public string NormalizeMethodName (MethodReference method) + { + return method.DeclaringType.GetElementType ().FullName + "." + method.Name; + } + + public TypeReference TypeParameter (string type, int position) + { + for (int i = stack.Count - 1; i >= 0; i--) { + var candidate = GenericTypeFor (stack [i]); + + if (candidate.FullName != type) + continue; + + return candidate.GenericParameters [position]; + } + + throw new InvalidOperationException (); + } + + static TypeReference GenericTypeFor (IGenericParameterProvider context) + { + var type = context as TypeReference; + if (type != null) + return type.GetElementType (); + + var method = context as MethodReference; + if (method != null) + return method.DeclaringType.GetElementType (); + + throw new InvalidOperationException (); + } + + public static ImportGenericContext For (IGenericParameterProvider context) + { + return context != null ? new ImportGenericContext (context) : default (ImportGenericContext); + } + } + + public class DefaultReflectionImporter : IReflectionImporter { + + readonly protected ModuleDefinition module; + + public DefaultReflectionImporter (ModuleDefinition module) + { + Mixin.CheckModule (module); + + this.module = module; + } + + enum ImportGenericKind { + Definition, + Open, + } + + static readonly Dictionary type_etype_mapping = new Dictionary (18) { + { typeof (void), ElementType.Void }, + { typeof (bool), ElementType.Boolean }, + { typeof (char), ElementType.Char }, + { typeof (sbyte), ElementType.I1 }, + { typeof (byte), ElementType.U1 }, + { typeof (short), ElementType.I2 }, + { typeof (ushort), ElementType.U2 }, + { typeof (int), ElementType.I4 }, + { typeof (uint), ElementType.U4 }, + { typeof (long), ElementType.I8 }, + { typeof (ulong), ElementType.U8 }, + { typeof (float), ElementType.R4 }, + { typeof (double), ElementType.R8 }, + { typeof (string), ElementType.String }, +#if !NET_CORE + { typeof (TypedReference), ElementType.TypedByRef }, +#endif + { typeof (IntPtr), ElementType.I }, + { typeof (UIntPtr), ElementType.U }, + { typeof (object), ElementType.Object }, + }; + + TypeReference ImportType (Type type, ImportGenericContext context) + { + return ImportType (type, context, ImportGenericKind.Open); + } + + TypeReference ImportType (Type type, ImportGenericContext context, ImportGenericKind import_kind) + { + if (IsTypeSpecification (type) || ImportOpenGenericType (type, import_kind)) + return ImportTypeSpecification (type, context); + + var reference = new TypeReference ( + string.Empty, + type.Name, + module, + ImportScope (type.Assembly ()), + type.IsValueType ()); + + reference.etype = ImportElementType (type); + + if (IsNestedType (type)) + reference.DeclaringType = ImportType (type.DeclaringType, context, import_kind); + else + reference.Namespace = type.Namespace ?? string.Empty; + + if (type.IsGenericType ()) + ImportGenericParameters (reference, type.GetGenericArguments ()); + + return reference; + } + + static bool ImportOpenGenericType (Type type, ImportGenericKind import_kind) + { + return type.IsGenericType () && type.IsGenericTypeDefinition () && import_kind == ImportGenericKind.Open; + } + + static bool ImportOpenGenericMethod (SR.MethodBase method, ImportGenericKind import_kind) + { + return method.IsGenericMethod && method.IsGenericMethodDefinition && import_kind == ImportGenericKind.Open; + } + + static bool IsNestedType (Type type) + { + return type.IsNested; + } + + TypeReference ImportTypeSpecification (Type type, ImportGenericContext context) + { + if (type.IsByRef) + return new ByReferenceType (ImportType (type.GetElementType (), context)); + + if (type.IsPointer) + return new PointerType (ImportType (type.GetElementType (), context)); + + if (type.IsArray) + return new ArrayType (ImportType (type.GetElementType (), context), type.GetArrayRank ()); + + if (type.IsGenericType ()) + return ImportGenericInstance (type, context); + + if (type.IsGenericParameter) + return ImportGenericParameter (type, context); + + throw new NotSupportedException (type.FullName); + } + + static TypeReference ImportGenericParameter (Type type, ImportGenericContext context) + { + if (context.IsEmpty) + throw new InvalidOperationException (); + + if (type.DeclaringMethod () != null) + return context.MethodParameter (NormalizeMethodName (type.DeclaringMethod ()), type.GenericParameterPosition); + + if (type.DeclaringType != null) + return context.TypeParameter (NormalizeTypeFullName (type.DeclaringType), type.GenericParameterPosition); + + throw new InvalidOperationException(); + } + + static string NormalizeMethodName (SR.MethodBase method) + { + return NormalizeTypeFullName (method.DeclaringType) + "." + method.Name; + } + + static string NormalizeTypeFullName (Type type) + { + if (IsNestedType (type)) + return NormalizeTypeFullName (type.DeclaringType) + "/" + type.Name; + + return type.FullName; + } + + TypeReference ImportGenericInstance (Type type, ImportGenericContext context) + { + var element_type = ImportType (type.GetGenericTypeDefinition (), context, ImportGenericKind.Definition); + var instance = new GenericInstanceType (element_type); + var arguments = type.GetGenericArguments (); + var instance_arguments = instance.GenericArguments; + + context.Push (element_type); + try { + for (int i = 0; i < arguments.Length; i++) + instance_arguments.Add (ImportType (arguments [i], context)); + + return instance; + } finally { + context.Pop (); + } + } + + static bool IsTypeSpecification (Type type) + { + return type.HasElementType + || IsGenericInstance (type) + || type.IsGenericParameter; + } + + static bool IsGenericInstance (Type type) + { + return type.IsGenericType () && !type.IsGenericTypeDefinition (); + } + + static ElementType ImportElementType (Type type) + { + ElementType etype; + if (!type_etype_mapping.TryGetValue (type, out etype)) + return ElementType.None; + + return etype; + } + + AssemblyNameReference ImportScope (SR.Assembly assembly) + { + return ImportReference (assembly.GetName ()); + } + + public virtual AssemblyNameReference ImportReference (SR.AssemblyName name) + { + Mixin.CheckName (name); + + AssemblyNameReference reference; + if (TryGetAssemblyNameReference (name, out reference)) + return reference; + + reference = new AssemblyNameReference (name.Name, name.Version) + { + PublicKeyToken = name.GetPublicKeyToken (), +#if !NET_CORE + Culture = name.CultureInfo.Name, + HashAlgorithm = (AssemblyHashAlgorithm) name.HashAlgorithm, +#endif + }; + + module.AssemblyReferences.Add (reference); + + return reference; + } + + bool TryGetAssemblyNameReference (SR.AssemblyName name, out AssemblyNameReference assembly_reference) + { + var references = module.AssemblyReferences; + + for (int i = 0; i < references.Count; i++) { + var reference = references [i]; + if (name.FullName != reference.FullName) // TODO compare field by field + continue; + + assembly_reference = reference; + return true; + } + + assembly_reference = null; + return false; + } + + FieldReference ImportField (SR.FieldInfo field, ImportGenericContext context) + { + var declaring_type = ImportType (field.DeclaringType, context); + + if (IsGenericInstance (field.DeclaringType)) + field = ResolveFieldDefinition (field); + + context.Push (declaring_type); + try { + return new FieldReference { + Name = field.Name, + DeclaringType = declaring_type, + FieldType = ImportType (field.FieldType, context), + }; + } finally { + context.Pop (); + } + } + + static SR.FieldInfo ResolveFieldDefinition (SR.FieldInfo field) + { +#if NET_CORE + throw new NotImplementedException (); +#else + return field.Module.ResolveField (field.MetadataToken); +#endif + } + + static SR.MethodBase ResolveMethodDefinition (SR.MethodBase method) + { +#if NET_CORE + throw new NotImplementedException (); +#else + return method.Module.ResolveMethod (method.MetadataToken); +#endif + } + + MethodReference ImportMethod (SR.MethodBase method, ImportGenericContext context, ImportGenericKind import_kind) + { + if (IsMethodSpecification (method) || ImportOpenGenericMethod (method, import_kind)) + return ImportMethodSpecification (method, context); + + var declaring_type = ImportType (method.DeclaringType, context); + + if (IsGenericInstance (method.DeclaringType)) + method = ResolveMethodDefinition (method); + + var reference = new MethodReference { + Name = method.Name, + HasThis = HasCallingConvention (method, SR.CallingConventions.HasThis), + ExplicitThis = HasCallingConvention (method, SR.CallingConventions.ExplicitThis), + DeclaringType = ImportType (method.DeclaringType, context, ImportGenericKind.Definition), + }; + + if (HasCallingConvention (method, SR.CallingConventions.VarArgs)) + reference.CallingConvention &= MethodCallingConvention.VarArg; + + if (method.IsGenericMethod) + ImportGenericParameters (reference, method.GetGenericArguments ()); + + context.Push (reference); + try { + var method_info = method as SR.MethodInfo; + reference.ReturnType = method_info != null + ? ImportType (method_info.ReturnType, context) + : ImportType (typeof (void), default (ImportGenericContext)); + + var parameters = method.GetParameters (); + var reference_parameters = reference.Parameters; + + for (int i = 0; i < parameters.Length; i++) + reference_parameters.Add ( + new ParameterDefinition (ImportType (parameters [i].ParameterType, context))); + + reference.DeclaringType = declaring_type; + + return reference; + } finally { + context.Pop (); + } + } + + static void ImportGenericParameters (IGenericParameterProvider provider, Type [] arguments) + { + var provider_parameters = provider.GenericParameters; + + for (int i = 0; i < arguments.Length; i++) + provider_parameters.Add (new GenericParameter (arguments [i].Name, provider)); + } + + static bool IsMethodSpecification (SR.MethodBase method) + { + return method.IsGenericMethod && !method.IsGenericMethodDefinition; + } + + MethodReference ImportMethodSpecification (SR.MethodBase method, ImportGenericContext context) + { + var method_info = method as SR.MethodInfo; + if (method_info == null) + throw new InvalidOperationException (); + + var element_method = ImportMethod (method_info.GetGenericMethodDefinition (), context, ImportGenericKind.Definition); + var instance = new GenericInstanceMethod (element_method); + var arguments = method.GetGenericArguments (); + var instance_arguments = instance.GenericArguments; + + context.Push (element_method); + try { + for (int i = 0; i < arguments.Length; i++) + instance_arguments.Add (ImportType (arguments [i], context)); + + return instance; + } finally { + context.Pop (); + } + } + + static bool HasCallingConvention (SR.MethodBase method, SR.CallingConventions conventions) + { + return (method.CallingConvention & conventions) != 0; + } + + public virtual TypeReference ImportReference (Type type, IGenericParameterProvider context) + { + Mixin.CheckType (type); + return ImportType ( + type, + ImportGenericContext.For (context), + context != null ? ImportGenericKind.Open : ImportGenericKind.Definition); + } + + public virtual FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context) + { + Mixin.CheckField (field); + return ImportField (field, ImportGenericContext.For (context)); + } + + public virtual MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context) + { + Mixin.CheckMethod (method); + return ImportMethod (method, + ImportGenericContext.For (context), + context != null ? ImportGenericKind.Open : ImportGenericKind.Definition); + } + } + + public class DefaultMetadataImporter : IMetadataImporter { + + readonly protected ModuleDefinition module; + + public DefaultMetadataImporter (ModuleDefinition module) + { + Mixin.CheckModule (module); + + this.module = module; + } + + TypeReference ImportType (TypeReference type, ImportGenericContext context) + { + if (type.IsTypeSpecification ()) + return ImportTypeSpecification (type, context); + + var reference = new TypeReference ( + type.Namespace, + type.Name, + module, + ImportScope (type.Scope), + type.IsValueType); + + MetadataSystem.TryProcessPrimitiveTypeReference (reference); + + if (type.IsNested) + reference.DeclaringType = ImportType (type.DeclaringType, context); + + if (type.HasGenericParameters) + ImportGenericParameters (reference, type); + + return reference; + } + + IMetadataScope ImportScope (IMetadataScope scope) + { + switch (scope.MetadataScopeType) { + case MetadataScopeType.AssemblyNameReference: + return ImportReference ((AssemblyNameReference) scope); + case MetadataScopeType.ModuleDefinition: + if (scope == module) return scope; + return ImportReference (((ModuleDefinition) scope).Assembly.Name); + case MetadataScopeType.ModuleReference: + throw new NotImplementedException (); + } + + throw new NotSupportedException (); + } + + public virtual AssemblyNameReference ImportReference (AssemblyNameReference name) + { + Mixin.CheckName (name); + + AssemblyNameReference reference; + if (module.TryGetAssemblyNameReference (name, out reference)) + return reference; + + reference = new AssemblyNameReference (name.Name, name.Version) { + Culture = name.Culture, + HashAlgorithm = name.HashAlgorithm, + IsRetargetable = name.IsRetargetable, + IsWindowsRuntime = name.IsWindowsRuntime, + }; + + var pk_token = !name.PublicKeyToken.IsNullOrEmpty () + ? new byte [name.PublicKeyToken.Length] + : Empty.Array; + + if (pk_token.Length > 0) + Buffer.BlockCopy (name.PublicKeyToken, 0, pk_token, 0, pk_token.Length); + + reference.PublicKeyToken = pk_token; + + module.AssemblyReferences.Add (reference); + + return reference; + } + + static void ImportGenericParameters (IGenericParameterProvider imported, IGenericParameterProvider original) + { + var parameters = original.GenericParameters; + var imported_parameters = imported.GenericParameters; + + for (int i = 0; i < parameters.Count; i++) + imported_parameters.Add (new GenericParameter (parameters [i].Name, imported)); + } + + TypeReference ImportTypeSpecification (TypeReference type, ImportGenericContext context) + { + switch (type.etype) { + case ElementType.SzArray: + var vector = (ArrayType) type; + return new ArrayType (ImportType (vector.ElementType, context)); + case ElementType.Ptr: + var pointer = (PointerType) type; + return new PointerType (ImportType (pointer.ElementType, context)); + case ElementType.ByRef: + var byref = (ByReferenceType) type; + return new ByReferenceType (ImportType (byref.ElementType, context)); + case ElementType.Pinned: + var pinned = (PinnedType) type; + return new PinnedType (ImportType (pinned.ElementType, context)); + case ElementType.Sentinel: + var sentinel = (SentinelType) type; + return new SentinelType (ImportType (sentinel.ElementType, context)); + case ElementType.FnPtr: + var fnptr = (FunctionPointerType) type; + var imported_fnptr = new FunctionPointerType () { + HasThis = fnptr.HasThis, + ExplicitThis = fnptr.ExplicitThis, + CallingConvention = fnptr.CallingConvention, + ReturnType = ImportType (fnptr.ReturnType, context), + }; + + if (!fnptr.HasParameters) + return imported_fnptr; + + for (int i = 0; i < fnptr.Parameters.Count; i++) + imported_fnptr.Parameters.Add (new ParameterDefinition ( + ImportType (fnptr.Parameters [i].ParameterType, context))); + + return imported_fnptr; + case ElementType.CModOpt: + var modopt = (OptionalModifierType) type; + return new OptionalModifierType ( + ImportType (modopt.ModifierType, context), + ImportType (modopt.ElementType, context)); + case ElementType.CModReqD: + var modreq = (RequiredModifierType) type; + return new RequiredModifierType ( + ImportType (modreq.ModifierType, context), + ImportType (modreq.ElementType, context)); + case ElementType.Array: + var array = (ArrayType) type; + var imported_array = new ArrayType (ImportType (array.ElementType, context)); + if (array.IsVector) + return imported_array; + + var dimensions = array.Dimensions; + var imported_dimensions = imported_array.Dimensions; + + imported_dimensions.Clear (); + + for (int i = 0; i < dimensions.Count; i++) { + var dimension = dimensions [i]; + + imported_dimensions.Add (new ArrayDimension (dimension.LowerBound, dimension.UpperBound)); + } + + return imported_array; + case ElementType.GenericInst: + var instance = (GenericInstanceType) type; + var element_type = ImportType (instance.ElementType, context); + var imported_instance = new GenericInstanceType (element_type); + + var arguments = instance.GenericArguments; + var imported_arguments = imported_instance.GenericArguments; + + for (int i = 0; i < arguments.Count; i++) + imported_arguments.Add (ImportType (arguments [i], context)); + + return imported_instance; + case ElementType.Var: + var var_parameter = (GenericParameter) type; + if (var_parameter.DeclaringType == null) + throw new InvalidOperationException (); + return context.TypeParameter (var_parameter.DeclaringType.FullName, var_parameter.Position); + case ElementType.MVar: + var mvar_parameter = (GenericParameter) type; + if (mvar_parameter.DeclaringMethod == null) + throw new InvalidOperationException (); + return context.MethodParameter (context.NormalizeMethodName (mvar_parameter.DeclaringMethod), mvar_parameter.Position); + } + + throw new NotSupportedException (type.etype.ToString ()); + } + + FieldReference ImportField (FieldReference field, ImportGenericContext context) + { + var declaring_type = ImportType (field.DeclaringType, context); + + context.Push (declaring_type); + try { + return new FieldReference { + Name = field.Name, + DeclaringType = declaring_type, + FieldType = ImportType (field.FieldType, context), + }; + } finally { + context.Pop (); + } + } + + MethodReference ImportMethod (MethodReference method, ImportGenericContext context) + { + if (method.IsGenericInstance) + return ImportMethodSpecification (method, context); + + var declaring_type = ImportType (method.DeclaringType, context); + + var reference = new MethodReference { + Name = method.Name, + HasThis = method.HasThis, + ExplicitThis = method.ExplicitThis, + DeclaringType = declaring_type, + CallingConvention = method.CallingConvention, + }; + + if (method.HasGenericParameters) + ImportGenericParameters (reference, method); + + context.Push (reference); + try { + reference.ReturnType = ImportType (method.ReturnType, context); + + if (!method.HasParameters) + return reference; + + var parameters = method.Parameters; + var reference_parameters = reference.parameters = new ParameterDefinitionCollection (reference, parameters.Count); + for (int i = 0; i < parameters.Count; i++) + reference_parameters.Add ( + new ParameterDefinition (ImportType (parameters [i].ParameterType, context))); + + return reference; + } finally { + context.Pop(); + } + } + + MethodSpecification ImportMethodSpecification (MethodReference method, ImportGenericContext context) + { + if (!method.IsGenericInstance) + throw new NotSupportedException (); + + var instance = (GenericInstanceMethod) method; + var element_method = ImportMethod (instance.ElementMethod, context); + var imported_instance = new GenericInstanceMethod (element_method); + + var arguments = instance.GenericArguments; + var imported_arguments = imported_instance.GenericArguments; + + for (int i = 0; i < arguments.Count; i++) + imported_arguments.Add (ImportType (arguments [i], context)); + + return imported_instance; + } + + public virtual TypeReference ImportReference (TypeReference type, IGenericParameterProvider context) + { + Mixin.CheckType (type); + return ImportType (type, ImportGenericContext.For (context)); + } + + public virtual FieldReference ImportReference (FieldReference field, IGenericParameterProvider context) + { + Mixin.CheckField (field); + return ImportField (field, ImportGenericContext.For (context)); + } + + public virtual MethodReference ImportReference (MethodReference method, IGenericParameterProvider context) + { + Mixin.CheckMethod (method); + return ImportMethod (method, ImportGenericContext.For (context)); + } + } + +#endif + + static partial class Mixin { + + public static void CheckModule (ModuleDefinition module) + { + if (module == null) + throw new ArgumentNullException (Argument.module.ToString ()); + } + + public static bool TryGetAssemblyNameReference (this ModuleDefinition module, AssemblyNameReference name_reference, out AssemblyNameReference assembly_reference) + { + var references = module.AssemblyReferences; + + for (int i = 0; i < references.Count; i++) { + var reference = references [i]; + if (!Equals (name_reference, reference)) + continue; + + assembly_reference = reference; + return true; + } + + assembly_reference = null; + return false; + } + + static bool Equals (byte [] a, byte [] b) + { + if (ReferenceEquals (a, b)) + return true; + if (a == null) + return false; + if (a.Length != b.Length) + return false; + for (int i = 0; i < a.Length; i++) + if (a [i] != b [i]) + return false; + return true; + } + + static bool Equals (T a, T b) where T : class, IEquatable + { + if (ReferenceEquals (a, b)) + return true; + if (a == null) + return false; + return a.Equals (b); + } + + static bool Equals (AssemblyNameReference a, AssemblyNameReference b) + { + if (ReferenceEquals (a, b)) + return true; + if (a.Name != b.Name) + return false; + if (!Equals (a.Version, b.Version)) + return false; + if (a.Culture != b.Culture) + return false; + if (!Equals (a.PublicKeyToken, b.PublicKeyToken)) + return false; + return true; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/LinkedResource.cs b/Mono.Cecil.20/Mono.Cecil/LinkedResource.cs new file mode 100644 index 00000000..e53430ec --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/LinkedResource.cs @@ -0,0 +1,42 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public sealed class LinkedResource : Resource { + + internal byte [] hash; + string file; + + public byte [] Hash { + get { return hash; } + } + + public string File { + get { return file; } + set { file = value; } + } + + public override ResourceType ResourceType { + get { return ResourceType.Linked; } + } + + public LinkedResource (string name, ManifestResourceAttributes flags) + : base (name, flags) + { + } + + public LinkedResource (string name, ManifestResourceAttributes flags, string file) + : base (name, flags) + { + this.file = file; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/ManifestResourceAttributes.cs b/Mono.Cecil.20/Mono.Cecil/ManifestResourceAttributes.cs new file mode 100644 index 00000000..03ccb6b4 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/ManifestResourceAttributes.cs @@ -0,0 +1,21 @@ +// +// 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; + +namespace Mono.Cecil { + + [Flags] + public enum ManifestResourceAttributes : uint { + VisibilityMask = 0x0007, + Public = 0x0001, // The resource is exported from the Assembly + Private = 0x0002 // The resource is private to the Assembly + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MarshalInfo.cs b/Mono.Cecil.20/Mono.Cecil/MarshalInfo.cs similarity index 70% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/MarshalInfo.cs rename to Mono.Cecil.20/Mono.Cecil/MarshalInfo.cs index 9d587389..47d935e2 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MarshalInfo.cs +++ b/Mono.Cecil.20/Mono.Cecil/MarshalInfo.cs @@ -1,29 +1,11 @@ // -// MarshalInfo.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; diff --git a/Mono.Cecil.20/Mono.Cecil/MemberDefinitionCollection.cs b/Mono.Cecil.20/Mono.Cecil/MemberDefinitionCollection.cs new file mode 100644 index 00000000..3872b2a9 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/MemberDefinitionCollection.cs @@ -0,0 +1,74 @@ +// +// 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 Mono.Collections.Generic; + +namespace Mono.Cecil { + + sealed class MemberDefinitionCollection : Collection where T : IMemberDefinition { + + TypeDefinition container; + + internal MemberDefinitionCollection (TypeDefinition container) + { + this.container = container; + } + + internal MemberDefinitionCollection (TypeDefinition container, int capacity) + : base (capacity) + { + this.container = container; + } + + protected override void OnAdd (T item, int index) + { + Attach (item); + } + + protected sealed override void OnSet (T item, int index) + { + Attach (item); + } + + protected sealed override void OnInsert (T item, int index) + { + Attach (item); + } + + protected sealed override void OnRemove (T item, int index) + { + Detach (item); + } + + protected sealed override void OnClear () + { + foreach (var definition in this) + Detach (definition); + } + + void Attach (T element) + { + if (element.DeclaringType == container) + return; + + if (element.DeclaringType != null) + throw new ArgumentException ("Member already attached"); + + element.DeclaringType = this.container; + } + + static void Detach (T element) + { + element.DeclaringType = null; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberReference.cs b/Mono.Cecil.20/Mono.Cecil/MemberReference.cs similarity index 51% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberReference.cs rename to Mono.Cecil.20/Mono.Cecil/MemberReference.cs index b658c513..84fd38c5 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberReference.cs +++ b/Mono.Cecil.20/Mono.Cecil/MemberReference.cs @@ -1,31 +1,15 @@ // -// MemberReference.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // +using System; + namespace Mono.Cecil { public abstract class MemberReference : IMetadataTokenProvider { @@ -34,10 +18,16 @@ public abstract class MemberReference : IMetadataTokenProvider { TypeReference declaring_type; internal MetadataToken token; + internal object projection; public virtual string Name { get { return name; } - set { name = value; } + set { + if (IsWindowsRuntimeProjection && value != name) + throw new InvalidOperationException (); + + name = value; + } } public abstract string FullName { @@ -54,6 +44,15 @@ public MetadataToken MetadataToken { set { token = value; } } + public bool IsWindowsRuntimeProjection { + get { return projection != null; } + } + + internal MemberReferenceProjection WindowsRuntimeProjection { + get { return (MemberReferenceProjection) projection; } + set { projection = value; } + } + internal bool HasImage { get { var module = Module; @@ -72,7 +71,7 @@ public virtual bool IsDefinition { get { return false; } } - internal virtual bool ContainsGenericParameter { + public virtual bool ContainsGenericParameter { get { return declaring_type != null && declaring_type.ContainsGenericParameter; } } @@ -93,6 +92,13 @@ internal string MemberFullName () return declaring_type.FullName + "::" + name; } + public IMemberDefinition Resolve () + { + return ResolveDefinition (); + } + + protected abstract IMemberDefinition ResolveDefinition (); + public override string ToString () { return FullName; diff --git a/Mono.Cecil.20/Mono.Cecil/MetadataResolver.cs b/Mono.Cecil.20/Mono.Cecil/MetadataResolver.cs new file mode 100644 index 00000000..0f590aa5 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/MetadataResolver.cs @@ -0,0 +1,384 @@ +// +// 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 Mono.Collections.Generic; + +namespace Mono.Cecil { + + public interface IAssemblyResolver : IDisposable { + AssemblyDefinition Resolve (AssemblyNameReference name); + AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters); + + event AssemblyResolveEventHandler ResolveFailure; + } + + public interface IMetadataResolver { + TypeDefinition Resolve (TypeReference type); + FieldDefinition Resolve (FieldReference field); + MethodDefinition Resolve (MethodReference method); + } + +#if !NET_CORE + [Serializable] +#endif + public sealed class ResolutionException : Exception { + + readonly MemberReference member; + + public MemberReference Member { + get { return member; } + } + + public IMetadataScope Scope { + get { + var type = member as TypeReference; + if (type != null) + return type.Scope; + + var declaring_type = member.DeclaringType; + if (declaring_type != null) + return declaring_type.Scope; + + throw new NotSupportedException (); + } + } + + public ResolutionException (MemberReference member) + : base ("Failed to resolve " + member.FullName) + { + if (member == null) + throw new ArgumentNullException ("member"); + + this.member = member; + } + +#if !NET_CORE + ResolutionException ( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) + : base (info, context) + { + } +#endif + } + + public class MetadataResolver : IMetadataResolver { + + readonly IAssemblyResolver assembly_resolver; + + public IAssemblyResolver AssemblyResolver { + get { return assembly_resolver; } + } + + public MetadataResolver (IAssemblyResolver assemblyResolver) + { + if (assemblyResolver == null) + throw new ArgumentNullException ("assemblyResolver"); + + assembly_resolver = assemblyResolver; + } + + public virtual TypeDefinition Resolve (TypeReference type) + { + Mixin.CheckType (type); + + type = type.GetElementType (); + + var scope = type.Scope; + + if (scope == null) + return null; + + switch (scope.MetadataScopeType) { + case MetadataScopeType.AssemblyNameReference: + var assembly = assembly_resolver.Resolve ((AssemblyNameReference) scope); + if (assembly == null) + return null; + + return GetType (assembly.MainModule, type); + case MetadataScopeType.ModuleDefinition: + return GetType ((ModuleDefinition) scope, type); + case MetadataScopeType.ModuleReference: + var modules = type.Module.Assembly.Modules; + var module_ref = (ModuleReference) scope; + for (int i = 0; i < modules.Count; i++) { + var netmodule = modules [i]; + if (netmodule.Name == module_ref.Name) + return GetType (netmodule, type); + } + break; + } + + throw new NotSupportedException (); + } + + static TypeDefinition GetType (ModuleDefinition module, TypeReference reference) + { + var type = GetTypeDefinition (module, reference); + if (type != null) + return type; + + if (!module.HasExportedTypes) + return null; + + var exported_types = module.ExportedTypes; + + for (int i = 0; i < exported_types.Count; i++) { + var exported_type = exported_types [i]; + if (exported_type.Name != reference.Name) + continue; + + if (exported_type.Namespace != reference.Namespace) + continue; + + return exported_type.Resolve (); + } + + return null; + } + + static TypeDefinition GetTypeDefinition (ModuleDefinition module, TypeReference type) + { + if (!type.IsNested) + return module.GetType (type.Namespace, type.Name); + + var declaring_type = type.DeclaringType.Resolve (); + if (declaring_type == null) + return null; + + return declaring_type.GetNestedType (type.TypeFullName ()); + } + + public virtual FieldDefinition Resolve (FieldReference field) + { + Mixin.CheckField (field); + + var type = Resolve (field.DeclaringType); + if (type == null) + return null; + + if (!type.HasFields) + return null; + + return GetField (type, field); + } + + FieldDefinition GetField (TypeDefinition type, FieldReference reference) + { + while (type != null) { + var field = GetField (type.Fields, reference); + if (field != null) + return field; + + if (type.BaseType == null) + return null; + + type = Resolve (type.BaseType); + } + + return null; + } + + static FieldDefinition GetField (Collection fields, FieldReference reference) + { + for (int i = 0; i < fields.Count; i++) { + var field = fields [i]; + + if (field.Name != reference.Name) + continue; + + if (!AreSame (field.FieldType, reference.FieldType)) + continue; + + return field; + } + + return null; + } + + public virtual MethodDefinition Resolve (MethodReference method) + { + Mixin.CheckMethod (method); + + var type = Resolve (method.DeclaringType); + if (type == null) + return null; + + method = method.GetElementMethod (); + + if (!type.HasMethods) + return null; + + return GetMethod (type, method); + } + + MethodDefinition GetMethod (TypeDefinition type, MethodReference reference) + { + while (type != null) { + var method = GetMethod (type.Methods, reference); + if (method != null) + return method; + + if (type.BaseType == null) + return null; + + type = Resolve (type.BaseType); + } + + return null; + } + + public static MethodDefinition GetMethod (Collection methods, MethodReference reference) + { + for (int i = 0; i < methods.Count; i++) { + var method = methods [i]; + + if (method.Name != reference.Name) + continue; + + if (method.HasGenericParameters != reference.HasGenericParameters) + continue; + + if (method.HasGenericParameters && method.GenericParameters.Count != reference.GenericParameters.Count) + continue; + + if (!AreSame (method.ReturnType, reference.ReturnType)) + continue; + + if (method.IsVarArg () != reference.IsVarArg ()) + continue; + + if (method.IsVarArg () && IsVarArgCallTo (method, reference)) + return method; + + if (method.HasParameters != reference.HasParameters) + continue; + + if (!method.HasParameters && !reference.HasParameters) + return method; + + if (!AreSame (method.Parameters, reference.Parameters)) + continue; + + return method; + } + + return null; + } + + static bool AreSame (Collection a, Collection b) + { + var count = a.Count; + + if (count != b.Count) + return false; + + if (count == 0) + return true; + + for (int i = 0; i < count; i++) + if (!AreSame (a [i].ParameterType, b [i].ParameterType)) + return false; + + return true; + } + + static bool IsVarArgCallTo (MethodDefinition method, MethodReference reference) + { + if (method.Parameters.Count >= reference.Parameters.Count) + return false; + + if (reference.GetSentinelPosition () != method.Parameters.Count) + return false; + + for (int i = 0; i < method.Parameters.Count; i++) + if (!AreSame (method.Parameters [i].ParameterType, reference.Parameters [i].ParameterType)) + return false; + + return true; + } + + static bool AreSame (TypeSpecification a, TypeSpecification b) + { + if (!AreSame (a.ElementType, b.ElementType)) + return false; + + if (a.IsGenericInstance) + return AreSame ((GenericInstanceType) a, (GenericInstanceType) b); + + if (a.IsRequiredModifier || a.IsOptionalModifier) + return AreSame ((IModifierType) a, (IModifierType) b); + + if (a.IsArray) + return AreSame ((ArrayType) a, (ArrayType) b); + + return true; + } + + static bool AreSame (ArrayType a, ArrayType b) + { + if (a.Rank != b.Rank) + return false; + + // TODO: dimensions + + return true; + } + + static bool AreSame (IModifierType a, IModifierType b) + { + return AreSame (a.ModifierType, b.ModifierType); + } + + static bool AreSame (GenericInstanceType a, GenericInstanceType b) + { + if (a.GenericArguments.Count != b.GenericArguments.Count) + return false; + + for (int i = 0; i < a.GenericArguments.Count; i++) + if (!AreSame (a.GenericArguments [i], b.GenericArguments [i])) + return false; + + return true; + } + + static bool AreSame (GenericParameter a, GenericParameter b) + { + return a.Position == b.Position; + } + + static bool AreSame (TypeReference a, TypeReference b) + { + if (ReferenceEquals (a, b)) + return true; + + if (a == null || b == null) + return false; + + if (a.etype != b.etype) + return false; + + if (a.IsGenericParameter) + return AreSame ((GenericParameter) a, (GenericParameter) b); + + if (a.IsTypeSpecification ()) + return AreSame ((TypeSpecification) a, (TypeSpecification) b); + + if (a.Name != b.Name || a.Namespace != b.Namespace) + return false; + + //TODO: check scope + + return AreSame (a.DeclaringType, b.DeclaringType); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataSystem.cs b/Mono.Cecil.20/Mono.Cecil/MetadataSystem.cs similarity index 63% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataSystem.cs rename to Mono.Cecil.20/Mono.Cecil/MetadataSystem.cs index 25cc8335..6a2dd345 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataSystem.cs +++ b/Mono.Cecil.20/Mono.Cecil/MetadataSystem.cs @@ -1,35 +1,19 @@ // -// MetadataSystem.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; using System.Collections.Generic; +using Mono.Cecil.Cil; using Mono.Cecil.Metadata; +using Mono.Collections.Generic; namespace Mono.Cecil { @@ -56,23 +40,29 @@ sealed class MetadataSystem { internal MethodDefinition [] Methods; internal MemberReference [] MemberReferences; - internal Dictionary NestedTypes; + internal Dictionary> NestedTypes; internal Dictionary ReverseNestedTypes; - internal Dictionary Interfaces; + internal Dictionary>> Interfaces; internal Dictionary> ClassLayouts; internal Dictionary FieldLayouts; internal Dictionary FieldRVAs; internal Dictionary FieldMarshals; internal Dictionary> Constants; - internal Dictionary Overrides; - internal Dictionary CustomAttributes; - internal Dictionary SecurityDeclarations; + internal Dictionary> Overrides; + internal Dictionary CustomAttributes; + internal Dictionary SecurityDeclarations; internal Dictionary Events; internal Dictionary Properties; internal Dictionary> Semantics; internal Dictionary> PInvokes; - internal Dictionary GenericParameters; - internal Dictionary GenericConstraints; + 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; @@ -125,7 +115,7 @@ public static bool TryGetPrimitiveElementType (TypeDefinition type, out ElementT return false; Row primitive_data; - if (TryGetPrimitiveData (type, out primitive_data) &&Mixin .IsPrimitive (primitive_data.Col1)) { + if (TryGetPrimitiveData (type, out primitive_data)) { etype = primitive_data.Col1; return true; } @@ -143,23 +133,36 @@ static bool TryGetPrimitiveData (TypeReference type, out Row public void Clear () { - if (NestedTypes != null) NestedTypes.Clear (); - if (ReverseNestedTypes != null) ReverseNestedTypes.Clear (); - if (Interfaces != null) Interfaces.Clear (); - if (ClassLayouts != null) ClassLayouts.Clear (); - if (FieldLayouts != null) FieldLayouts.Clear (); - if (FieldRVAs != null) FieldRVAs.Clear (); - if (FieldMarshals != null) FieldMarshals.Clear (); - if (Constants != null) Constants.Clear (); - if (Overrides != null) Overrides.Clear (); - if (CustomAttributes != null) CustomAttributes.Clear (); - if (SecurityDeclarations != null) SecurityDeclarations.Clear (); - if (Events != null) Events.Clear (); - if (Properties != null) Properties.Clear (); - if (Semantics != null) Semantics.Clear (); - if (PInvokes != null) PInvokes.Clear (); - if (GenericParameters != null) GenericParameters.Clear (); - if (GenericConstraints != null) GenericConstraints.Clear (); + if (NestedTypes != null) NestedTypes = new Dictionary> (capacity: 0); + if (ReverseNestedTypes != null) ReverseNestedTypes = new Dictionary (capacity: 0); + if (Interfaces != null) Interfaces = new Dictionary>> (capacity: 0); + if (ClassLayouts != null) ClassLayouts = new Dictionary> (capacity: 0); + if (FieldLayouts != null) FieldLayouts = new Dictionary (capacity: 0); + if (FieldRVAs != null) FieldRVAs = new Dictionary (capacity: 0); + if (FieldMarshals != null) FieldMarshals = new Dictionary (capacity: 0); + if (Constants != null) Constants = new Dictionary> (capacity: 0); + if (Overrides != null) Overrides = new Dictionary> (capacity: 0); + if (CustomAttributes != null) CustomAttributes = new Dictionary (capacity: 0); + if (SecurityDeclarations != null) SecurityDeclarations = new Dictionary (capacity: 0); + if (Events != null) Events = new Dictionary (capacity: 0); + if (Properties != null) Properties = new Dictionary (capacity: 0); + if (Semantics != null) Semantics = new Dictionary> (capacity: 0); + if (PInvokes != null) PInvokes = new Dictionary> (capacity: 0); + if (GenericParameters != null) GenericParameters = new Dictionary (capacity: 0); + if (GenericConstraints != null) GenericConstraints = new Dictionary> (capacity: 0); + + Documents = Empty.Array; + ImportScopes = Empty.Array; + if (LocalScopes != null) LocalScopes = new Dictionary>> (capacity: 0); + if (StateMachineMethods != null) StateMachineMethods = new Dictionary (capacity: 0); + } + + public AssemblyNameReference GetAssemblyNameReference (uint rid) + { + if (rid < 1 || rid > AssemblyReferences.Length) + return null; + + return AssemblyReferences [rid - 1]; } public TypeDefinition GetTypeDefinition (uint rid) @@ -227,12 +230,12 @@ public void AddMemberReference (MemberReference member) MemberReferences [member.token.RID - 1] = member; } - public bool TryGetNestedTypeMapping (TypeDefinition type, out uint [] mapping) + public bool TryGetNestedTypeMapping (TypeDefinition type, out Collection mapping) { return NestedTypes.TryGetValue (type.token.RID, out mapping); } - public void SetNestedTypeMapping (uint type_rid, uint [] mapping) + public void SetNestedTypeMapping (uint type_rid, Collection mapping) { NestedTypes [type_rid] = mapping; } @@ -249,7 +252,7 @@ public bool TryGetReverseNestedTypeMapping (TypeDefinition type, out uint declar public void SetReverseNestedTypeMapping (uint nested, uint declaring) { - ReverseNestedTypes.Add (nested, declaring); + ReverseNestedTypes [nested] = declaring; } public void RemoveReverseNestedTypeMapping (TypeDefinition type) @@ -257,12 +260,12 @@ public void RemoveReverseNestedTypeMapping (TypeDefinition type) ReverseNestedTypes.Remove (type.token.RID); } - public bool TryGetInterfaceMapping (TypeDefinition type, out MetadataToken [] mapping) + public bool TryGetInterfaceMapping (TypeDefinition type, out Collection> mapping) { return Interfaces.TryGetValue (type.token.RID, out mapping); } - public void SetInterfaceMapping (uint type_rid, MetadataToken [] mapping) + public void SetInterfaceMapping (uint type_rid, Collection> mapping) { Interfaces [type_rid] = mapping; } @@ -302,9 +305,9 @@ public void RemoveEventsRange (TypeDefinition type) Events.Remove (type.token.RID); } - public bool TryGetGenericParameterRange (IGenericParameterProvider owner, out Range range) + public bool TryGetGenericParameterRanges (IGenericParameterProvider owner, out Range [] ranges) { - return GenericParameters.TryGetValue (owner.MetadataToken, out range); + return GenericParameters.TryGetValue (owner.MetadataToken, out ranges); } public void RemoveGenericParameterRange (IGenericParameterProvider owner) @@ -312,9 +315,9 @@ public void RemoveGenericParameterRange (IGenericParameterProvider owner) GenericParameters.Remove (owner.MetadataToken); } - public bool TryGetCustomAttributeRange (ICustomAttributeProvider owner, out Range range) + public bool TryGetCustomAttributeRanges (ICustomAttributeProvider owner, out Range [] ranges) { - return CustomAttributes.TryGetValue (owner.MetadataToken, out range); + return CustomAttributes.TryGetValue (owner.MetadataToken, out ranges); } public void RemoveCustomAttributeRange (ICustomAttributeProvider owner) @@ -322,9 +325,9 @@ public void RemoveCustomAttributeRange (ICustomAttributeProvider owner) CustomAttributes.Remove (owner.MetadataToken); } - public bool TryGetSecurityDeclarationRange (ISecurityDeclarationProvider owner, out Range range) + public bool TryGetSecurityDeclarationRanges (ISecurityDeclarationProvider owner, out Range [] ranges) { - return SecurityDeclarations.TryGetValue (owner.MetadataToken, out range); + return SecurityDeclarations.TryGetValue (owner.MetadataToken, out ranges); } public void RemoveSecurityDeclarationRange (ISecurityDeclarationProvider owner) @@ -332,12 +335,12 @@ public void RemoveSecurityDeclarationRange (ISecurityDeclarationProvider owner) SecurityDeclarations.Remove (owner.MetadataToken); } - public bool TryGetGenericConstraintMapping (GenericParameter generic_parameter, out MetadataToken [] mapping) + public bool TryGetGenericConstraintMapping (GenericParameter generic_parameter, out Collection mapping) { return GenericConstraints.TryGetValue (generic_parameter.token.RID, out mapping); } - public void SetGenericConstraintMapping (uint gp_rid, MetadataToken [] mapping) + public void SetGenericConstraintMapping (uint gp_rid, Collection mapping) { GenericConstraints [gp_rid] = mapping; } @@ -347,12 +350,12 @@ public void RemoveGenericConstraintMapping (GenericParameter generic_parameter) GenericConstraints.Remove (generic_parameter.token.RID); } - public bool TryGetOverrideMapping (MethodDefinition method, out MetadataToken [] mapping) + public bool TryGetOverrideMapping (MethodDefinition method, out Collection mapping) { return Overrides.TryGetValue (method.token.RID, out mapping); } - public void SetOverrideMapping (uint rid, MetadataToken [] mapping) + public void SetOverrideMapping (uint rid, Collection mapping) { Overrides [rid] = mapping; } @@ -362,6 +365,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 Collection> scopes) + { + return LocalScopes.TryGetValue (method.MetadataToken.RID, out scopes); + } + + public void SetLocalScopes (uint method_rid, Collection> 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.20/MonoCecil/Mono.Cecil/MethodAttributes.cs b/Mono.Cecil.20/Mono.Cecil/MethodAttributes.cs similarity index 58% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodAttributes.cs rename to Mono.Cecil.20/Mono.Cecil/MethodAttributes.cs index 97f4c292..1bd7d128 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodAttributes.cs +++ b/Mono.Cecil.20/Mono.Cecil/MethodAttributes.cs @@ -1,29 +1,11 @@ // -// MethodAttributes.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; @@ -36,7 +18,7 @@ public enum MethodAttributes : ushort { CompilerControlled = 0x0000, // Member not referenceable Private = 0x0001, // Accessible only by the parent type FamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly - Assembly = 0x0003, // Accessibly by anyone in the Assembly + Assembly = 0x0003, // Accessibly by anyone in the Assembly Family = 0x0004, // Accessible only by type and sub-types FamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly Public = 0x0006, // Accessibly by anyone who has visibility to this scope diff --git a/Mono.Cecil.20/Mono.Cecil/MethodCallingConvention.cs b/Mono.Cecil.20/Mono.Cecil/MethodCallingConvention.cs new file mode 100644 index 00000000..f9c0e0c9 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/MethodCallingConvention.cs @@ -0,0 +1,22 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum MethodCallingConvention : byte { + Default = 0x0, + C = 0x1, + StdCall = 0x2, + ThisCall = 0x3, + FastCall = 0x4, + VarArg = 0x5, + Generic = 0x10, + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/MethodDefinition.cs b/Mono.Cecil.20/Mono.Cecil/MethodDefinition.cs new file mode 100644 index 00000000..71de613c --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/MethodDefinition.cs @@ -0,0 +1,540 @@ +// +// 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 Mono.Cecil.Cil; +using Mono.Collections.Generic; + +using RVA = System.UInt32; + +namespace Mono.Cecil { + + public sealed class MethodDefinition : MethodReference, IMemberDefinition, ISecurityDeclarationProvider, ICustomDebugInformationProvider { + + ushort attributes; + ushort impl_attributes; + internal volatile bool sem_attrs_ready; + internal MethodSemanticsAttributes sem_attrs; + Collection custom_attributes; + Collection security_declarations; + + internal RVA rva; + internal PInvokeInfo pinvoke; + Collection overrides; + + internal MethodBody body; + internal MethodDebugInformation debug_info; + internal Collection custom_infos; + + public override string Name { + get { return base.Name; } + set { + if (IsWindowsRuntimeProjection && value != base.Name) + throw new InvalidOperationException (); + + base.Name = value; + } + } + + public MethodAttributes Attributes { + get { return (MethodAttributes) attributes; } + set { + if (IsWindowsRuntimeProjection && (ushort) value != attributes) + throw new InvalidOperationException (); + + attributes = (ushort) value; + } + } + + public MethodImplAttributes ImplAttributes { + get { return (MethodImplAttributes) impl_attributes; } + set { + if (IsWindowsRuntimeProjection && (ushort) value != impl_attributes) + throw new InvalidOperationException (); + + impl_attributes = (ushort) value; + } + } + + public MethodSemanticsAttributes SemanticsAttributes { + get { + if (sem_attrs_ready) + return sem_attrs; + + if (HasImage) { + ReadSemantics (); + return sem_attrs; + } + + sem_attrs = MethodSemanticsAttributes.None; + sem_attrs_ready = true; + return sem_attrs; + } + set { sem_attrs = value; } + } + + internal new MethodDefinitionProjection WindowsRuntimeProjection { + get { return (MethodDefinitionProjection) projection; } + set { projection = value; } + } + + internal void ReadSemantics () + { + if (sem_attrs_ready) + return; + + var module = this.Module; + if (module == null) + return; + + if (!module.HasImage) + return; + + module.Read (this, (method, reader) => reader.ReadAllSemantics (method)); + } + + public bool HasSecurityDeclarations { + get { + if (security_declarations != null) + return security_declarations.Count > 0; + + return this.GetHasSecurityDeclarations (Module); + } + } + + public Collection SecurityDeclarations { + get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return this.GetHasCustomAttributes (Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } + } + + public int RVA { + get { return (int) rva; } + } + + public bool HasBody { + get { + return (attributes & (ushort) MethodAttributes.Abstract) == 0 && + (attributes & (ushort) MethodAttributes.PInvokeImpl) == 0 && + (impl_attributes & (ushort) MethodImplAttributes.InternalCall) == 0 && + (impl_attributes & (ushort) MethodImplAttributes.Native) == 0 && + (impl_attributes & (ushort) MethodImplAttributes.Unmanaged) == 0 && + (impl_attributes & (ushort) MethodImplAttributes.Runtime) == 0; + } + } + + public MethodBody Body { + get { + MethodBody localBody = this.body; + if (localBody != null) + return localBody; + + if (!HasBody) + return null; + + if (HasImage && rva != 0) + return Module.Read (ref body, this, (method, reader) => reader.ReadMethodBody (method)); + + return body = new MethodBody (this); + } + set { + var module = this.Module; + if (module == null) { + body = value; + return; + } + + // we reset Body to null in ILSpy to save memory; so we need that operation to be thread-safe + lock (module.SyncRoot) { + body = value; + } + } + } + + public MethodDebugInformation DebugInformation { + get { + Mixin.Read (Body); + + if (debug_info != null) + return debug_info; + + return debug_info ?? (debug_info = new MethodDebugInformation (this)); + } + } + + public bool HasPInvokeInfo { + get { + if (pinvoke != null) + return true; + + return IsPInvokeImpl; + } + } + + public PInvokeInfo PInvokeInfo { + get { + if (pinvoke != null) + return pinvoke; + + if (HasImage && IsPInvokeImpl) + return Module.Read (ref pinvoke, this, (method, reader) => reader.ReadPInvokeInfo (method)); + + return null; + } + set { + IsPInvokeImpl = true; + pinvoke = value; + } + } + + public bool HasOverrides { + get { + if (overrides != null) + return overrides.Count > 0; + + return HasImage && Module.Read (this, (method, reader) => reader.HasOverrides (method)); + } + } + + public Collection Overrides { + get { + if (overrides != null) + return overrides; + + if (HasImage) + return Module.Read (ref overrides, this, (method, reader) => reader.ReadOverrides (method)); + + return overrides = new Collection (); + } + } + + public override bool HasGenericParameters { + get { + if (generic_parameters != null) + return generic_parameters.Count > 0; + + return this.GetHasGenericParameters (Module); + } + } + + 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 { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.CompilerControlled); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.CompilerControlled, value); } + } + + public bool IsPrivate { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Private); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Private, value); } + } + + public bool IsFamilyAndAssembly { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamANDAssem); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamANDAssem, value); } + } + + public bool IsAssembly { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Assembly); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Assembly, value); } + } + + public bool IsFamily { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Family); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Family, value); } + } + + public bool IsFamilyOrAssembly { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamORAssem); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamORAssem, value); } + } + + public bool IsPublic { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Public); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Public, value); } + } + + public bool IsStatic { + get { return attributes.GetAttributes ((ushort) MethodAttributes.Static); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Static, value); } + } + + public bool IsFinal { + get { return attributes.GetAttributes ((ushort) MethodAttributes.Final); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Final, value); } + } + + public bool IsVirtual { + get { return attributes.GetAttributes ((ushort) MethodAttributes.Virtual); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Virtual, value); } + } + + public bool IsHideBySig { + get { return attributes.GetAttributes ((ushort) MethodAttributes.HideBySig); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.HideBySig, value); } + } + + public bool IsReuseSlot { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.ReuseSlot); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.ReuseSlot, value); } + } + + public bool IsNewSlot { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.NewSlot); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.NewSlot, value); } + } + + public bool IsCheckAccessOnOverride { + get { return attributes.GetAttributes ((ushort) MethodAttributes.CheckAccessOnOverride); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.CheckAccessOnOverride, value); } + } + + public bool IsAbstract { + get { return attributes.GetAttributes ((ushort) MethodAttributes.Abstract); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Abstract, value); } + } + + public bool IsSpecialName { + get { return attributes.GetAttributes ((ushort) MethodAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.SpecialName, value); } + } + + public bool IsPInvokeImpl { + get { return attributes.GetAttributes ((ushort) MethodAttributes.PInvokeImpl); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.PInvokeImpl, value); } + } + + public bool IsUnmanagedExport { + get { return attributes.GetAttributes ((ushort) MethodAttributes.UnmanagedExport); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.UnmanagedExport, value); } + } + + public bool IsRuntimeSpecialName { + get { return attributes.GetAttributes ((ushort) MethodAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.RTSpecialName, value); } + } + + public bool HasSecurity { + get { return attributes.GetAttributes ((ushort) MethodAttributes.HasSecurity); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.HasSecurity, value); } + } + + #endregion + + #region MethodImplAttributes + + public bool IsIL { + get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL); } + set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL, value); } + } + + public bool IsNative { + get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Native); } + set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Native, value); } + } + + public bool IsRuntime { + get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Runtime); } + set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Runtime, value); } + } + + public bool IsUnmanaged { + get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Unmanaged); } + set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Unmanaged, value); } + } + + public bool IsManaged { + get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Managed); } + set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Managed, value); } + } + + public bool IsForwardRef { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.ForwardRef); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.ForwardRef, value); } + } + + public bool IsPreserveSig { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.PreserveSig); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.PreserveSig, value); } + } + + public bool IsInternalCall { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.InternalCall); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.InternalCall, value); } + } + + public bool IsSynchronized { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.Synchronized); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.Synchronized, value); } + } + + public bool NoInlining { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.NoInlining); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.NoInlining, value); } + } + + public bool NoOptimization { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.NoOptimization); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.NoOptimization, value); } + } + + public bool AggressiveInlining { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.AggressiveInlining); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.AggressiveInlining, value); } + } + + #endregion + + #region MethodSemanticsAttributes + + public bool IsSetter { + get { return this.GetSemantics (MethodSemanticsAttributes.Setter); } + set { this.SetSemantics (MethodSemanticsAttributes.Setter, value); } + } + + public bool IsGetter { + get { return this.GetSemantics (MethodSemanticsAttributes.Getter); } + set { this.SetSemantics (MethodSemanticsAttributes.Getter, value); } + } + + public bool IsOther { + get { return this.GetSemantics (MethodSemanticsAttributes.Other); } + set { this.SetSemantics (MethodSemanticsAttributes.Other, value); } + } + + public bool IsAddOn { + get { return this.GetSemantics (MethodSemanticsAttributes.AddOn); } + set { this.SetSemantics (MethodSemanticsAttributes.AddOn, value); } + } + + public bool IsRemoveOn { + get { return this.GetSemantics (MethodSemanticsAttributes.RemoveOn); } + set { this.SetSemantics (MethodSemanticsAttributes.RemoveOn, value); } + } + + public bool IsFire { + get { return this.GetSemantics (MethodSemanticsAttributes.Fire); } + set { this.SetSemantics (MethodSemanticsAttributes.Fire, value); } + } + + #endregion + + public new TypeDefinition DeclaringType { + get { return (TypeDefinition) base.DeclaringType; } + set { base.DeclaringType = value; } + } + + public bool IsConstructor { + get { + return this.IsRuntimeSpecialName + && this.IsSpecialName + && (this.Name == ".cctor" || this.Name == ".ctor"); + } + } + + public override bool IsDefinition { + get { return true; } + } + + internal MethodDefinition () + { + this.token = new MetadataToken (TokenType.Method); + } + + public MethodDefinition (string name, MethodAttributes attributes, TypeReference returnType) + : base (name, returnType) + { + this.attributes = (ushort) attributes; + this.HasThis = !this.IsStatic; + this.token = new MetadataToken (TokenType.Method); + } + + public override MethodDefinition Resolve () + { + return this; + } + } + + static partial class Mixin { + + public static ParameterDefinition GetParameter (this MethodBody self, int index) + { + var method = self.method; + + if (method.HasThis) { + if (index == 0) + return self.ThisParameter; + + index--; + } + + var parameters = method.Parameters; + + if (index < 0 || index >= parameters.size) + return null; + + return parameters [index]; + } + + public static VariableDefinition GetVariable (this MethodBody self, int index) + { + var variables = self.Variables; + + if (index < 0 || index >= variables.size) + return null; + + return variables [index]; + } + + public static bool GetSemantics (this MethodDefinition self, MethodSemanticsAttributes semantics) + { + return (self.SemanticsAttributes & semantics) != 0; + } + + public static void SetSemantics (this MethodDefinition self, MethodSemanticsAttributes semantics, bool value) + { + if (value) + self.SemanticsAttributes |= semantics; + else + self.SemanticsAttributes &= ~semantics; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/MethodImplAttributes.cs b/Mono.Cecil.20/Mono.Cecil/MethodImplAttributes.cs new file mode 100644 index 00000000..2f1f0183 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/MethodImplAttributes.cs @@ -0,0 +1,36 @@ +// +// 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; + +namespace Mono.Cecil { + + [Flags] + public enum MethodImplAttributes : ushort { + CodeTypeMask = 0x0003, + IL = 0x0000, // Method impl is CIL + Native = 0x0001, // Method impl is native + OPTIL = 0x0002, // Reserved: shall be zero in conforming implementations + Runtime = 0x0003, // Method impl is provided by the runtime + + ManagedMask = 0x0004, // Flags specifying whether the code is managed or unmanaged + Unmanaged = 0x0004, // Method impl is unmanaged, otherwise managed + Managed = 0x0000, // Method impl is managed + + // Implementation info and interop + ForwardRef = 0x0010, // Indicates method is defined; used primarily in merge scenarios + PreserveSig = 0x0080, // Reserved: conforming implementations may ignore + InternalCall = 0x1000, // Reserved: shall be zero in conforming implementations + Synchronized = 0x0020, // Method is single threaded through the body + NoOptimization = 0x0040, // Method is not optimized by the JIT. + NoInlining = 0x0008, // Method may not be inlined + AggressiveInlining = 0x0100, // Method should be inlined, if possible. + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/MethodReference.cs b/Mono.Cecil.20/Mono.Cecil/MethodReference.cs new file mode 100644 index 00000000..46508145 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/MethodReference.cs @@ -0,0 +1,211 @@ +// +// 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.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public class MethodReference : MemberReference, IMethodSignature, IGenericParameterProvider, IGenericContext { + + int hashCode = -1; + static int instance_id; + internal ParameterDefinitionCollection parameters; + MethodReturnType return_type; + + bool has_this; + bool explicit_this; + MethodCallingConvention calling_convention; + internal Collection generic_parameters; + + public virtual bool HasThis { + get { return has_this; } + set { has_this = value; } + } + + public virtual bool ExplicitThis { + get { return explicit_this; } + set { explicit_this = value; } + } + + public virtual MethodCallingConvention CallingConvention { + get { return calling_convention; } + set { calling_convention = value; } + } + + public virtual bool HasParameters { + get { return !parameters.IsNullOrEmpty (); } + } + + public virtual Collection Parameters { + get { + if (parameters == null) + parameters = new ParameterDefinitionCollection (this); + + return parameters; + } + } + + IGenericParameterProvider IGenericContext.Type { + get { + var declaring_type = this.DeclaringType; + var instance = declaring_type as GenericInstanceType; + if (instance != null) + return instance.ElementType; + + return declaring_type; + } + } + + IGenericParameterProvider IGenericContext.Method { + get { return this; } + } + + GenericParameterType IGenericParameterProvider.GenericParameterType { + get { return GenericParameterType.Method; } + } + + public virtual bool HasGenericParameters { + get { return !generic_parameters.IsNullOrEmpty (); } + } + + public virtual Collection GenericParameters { + get { + if (generic_parameters != null) + return generic_parameters; + + return generic_parameters = new GenericParameterCollection (this); + } + } + + public TypeReference ReturnType { + get { + var return_type = MethodReturnType; + return return_type != null ? return_type.ReturnType : null; + } + set { + var return_type = MethodReturnType; + if (return_type != null) + return_type.ReturnType = value; + } + } + + public virtual MethodReturnType MethodReturnType { + get { return return_type; } + set { return_type = value; } + } + + public override string FullName { + get { + var builder = new StringBuilder (); + builder.Append (ReturnType.FullName) + .Append (" ") + .Append (MemberFullName ()); + this.MethodSignatureFullName (builder); + return builder.ToString (); + } + } + + public override int GetHashCode() + { + if (hashCode == -1) + hashCode = System.Threading.Interlocked.Add(ref instance_id, 1); + return hashCode; + } + + public virtual bool IsGenericInstance { + get { return false; } + } + + public override bool ContainsGenericParameter { + get { + if (this.ReturnType.ContainsGenericParameter || base.ContainsGenericParameter) + return true; + + if (!HasParameters) + return false; + + var parameters = this.Parameters; + + for (int i = 0; i < parameters.Count; i++) + if (parameters [i].ParameterType.ContainsGenericParameter) + return true; + + return false; + } + } + + internal MethodReference () + { + this.return_type = new MethodReturnType (this); + this.token = new MetadataToken (TokenType.MemberRef); + } + + public MethodReference (string name, TypeReference returnType) + : base (name) + { + Mixin.CheckType (returnType, Mixin.Argument.returnType); + + this.return_type = new MethodReturnType (this); + this.return_type.ReturnType = returnType; + this.token = new MetadataToken (TokenType.MemberRef); + } + + public MethodReference (string name, TypeReference returnType, TypeReference declaringType) + : this (name, returnType) + { + Mixin.CheckType (declaringType, Mixin.Argument.declaringType); + + this.DeclaringType = declaringType; + } + + public virtual MethodReference GetElementMethod () + { + return this; + } + + protected override IMemberDefinition ResolveDefinition () + { + return this.Resolve (); + } + + public new virtual MethodDefinition Resolve () + { + var module = this.Module; + if (module == null) + throw new NotSupportedException (); + + return module.Resolve (this); + } + } + + static partial class Mixin { + + public static bool IsVarArg (this IMethodSignature self) + { + return (self.CallingConvention & MethodCallingConvention.VarArg) != 0; + } + + public static int GetSentinelPosition (this IMethodSignature self) + { + if (!self.HasParameters) + return -1; + + var parameters = self.Parameters; + for (int i = 0; i < parameters.Count; i++) + if (parameters [i].ParameterType.IsSentinel) + return i; + + return -1; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReturnType.cs b/Mono.Cecil.20/Mono.Cecil/MethodReturnType.cs similarity index 61% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReturnType.cs rename to Mono.Cecil.20/Mono.Cecil/MethodReturnType.cs index 0fab2f24..71a78de1 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReturnType.cs +++ b/Mono.Cecil.20/Mono.Cecil/MethodReturnType.cs @@ -1,29 +1,11 @@ // -// MethodReturnType.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System.Threading; @@ -50,7 +32,7 @@ public TypeReference ReturnType { internal ParameterDefinition Parameter { get { if (parameter == null) - parameter=new ParameterDefinition (return_type, method); + Interlocked.CompareExchange (ref parameter, new ParameterDefinition (return_type, method), null); return parameter; } @@ -66,6 +48,11 @@ public ParameterAttributes Attributes { set { Parameter.Attributes = value; } } + public string Name { + get { return Parameter.Name; } + set { Parameter.Name = value; } + } + public bool HasCustomAttributes { get { return parameter != null && parameter.HasCustomAttributes; } } diff --git a/Mono.Cecil.20/Mono.Cecil/MethodSemanticsAttributes.cs b/Mono.Cecil.20/Mono.Cecil/MethodSemanticsAttributes.cs new file mode 100644 index 00000000..274dfd04 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/MethodSemanticsAttributes.cs @@ -0,0 +1,25 @@ +// +// 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; + +namespace Mono.Cecil { + + [Flags] + public enum MethodSemanticsAttributes : ushort { + None = 0x0000, + Setter = 0x0001, // Setter for property + Getter = 0x0002, // Getter for property + Other = 0x0004, // Other method for property or event + AddOn = 0x0008, // AddOn method for event + RemoveOn = 0x0010, // RemoveOn method for event + Fire = 0x0020 // Fire method for event + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSpecification.cs b/Mono.Cecil.20/Mono.Cecil/MethodSpecification.cs similarity index 57% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSpecification.cs rename to Mono.Cecil.20/Mono.Cecil/MethodSpecification.cs index 73b5c14a..040be6ed 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSpecification.cs +++ b/Mono.Cecil.20/Mono.Cecil/MethodSpecification.cs @@ -1,29 +1,11 @@ // -// MethodSpecification.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; @@ -82,14 +64,13 @@ public override Collection Parameters { get { return method.Parameters; } } - internal override bool ContainsGenericParameter { + public override bool ContainsGenericParameter { get { return method.ContainsGenericParameter; } } internal MethodSpecification (MethodReference method) { - if (method == null) - throw new ArgumentNullException ("method"); + Mixin.CheckMethod (method); this.method = method; this.token = new MetadataToken (TokenType.MethodSpec); diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/Modifiers.cs b/Mono.Cecil.20/Mono.Cecil/Modifiers.cs similarity index 57% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/Modifiers.cs rename to Mono.Cecil.20/Mono.Cecil/Modifiers.cs index ad31bc04..9c50f0e4 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/Modifiers.cs +++ b/Mono.Cecil.20/Mono.Cecil/Modifiers.cs @@ -1,29 +1,11 @@ // -// Modifiers.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; @@ -67,14 +49,16 @@ public override bool IsOptionalModifier { get { return true; } } - internal override bool ContainsGenericParameter { + public override bool ContainsGenericParameter { get { return modifier_type.ContainsGenericParameter || base.ContainsGenericParameter; } } public OptionalModifierType (TypeReference modifierType, TypeReference type) : base (type) { - Mixin.CheckModifier (modifierType, type); + if (modifierType == null) + throw new ArgumentNullException (Mixin.Argument.modifierType.ToString ()); + Mixin.CheckType (type); this.modifier_type = modifierType; this.etype = MD.ElementType.CModOpt; } @@ -110,28 +94,19 @@ public override bool IsRequiredModifier { get { return true; } } - internal override bool ContainsGenericParameter { + public override bool ContainsGenericParameter { get { return modifier_type.ContainsGenericParameter || base.ContainsGenericParameter; } } public RequiredModifierType (TypeReference modifierType, TypeReference type) : base (type) { - Mixin.CheckModifier (modifierType, type); + if (modifierType == null) + throw new ArgumentNullException (Mixin.Argument.modifierType.ToString ()); + Mixin.CheckType (type); this.modifier_type = modifierType; this.etype = MD.ElementType.CModReqD; } } - - static partial class Mixin { - - public static void CheckModifier (TypeReference modifierType, TypeReference type) - { - if (modifierType == null) - throw new ArgumentNullException ("modifierType"); - if (type == null) - throw new ArgumentNullException ("type"); - } - } } diff --git a/Mono.Cecil.20/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil.20/Mono.Cecil/ModuleDefinition.cs new file mode 100644 index 00000000..d986d161 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/ModuleDefinition.cs @@ -0,0 +1,1344 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using SR = System.Reflection; + +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public enum ReadingMode { + Immediate = 1, + Deferred = 2, + } + + public sealed class ReaderParameters { + + ReadingMode reading_mode; + internal IAssemblyResolver assembly_resolver; + internal IMetadataResolver metadata_resolver; +#if !READ_ONLY + internal IMetadataImporterProvider metadata_importer_provider; + internal IReflectionImporterProvider reflection_importer_provider; +#endif + Stream symbol_stream; + ISymbolReaderProvider symbol_reader_provider; + bool read_symbols; + bool projections; + bool in_memory; + bool read_write; + + 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; } + } + + public IMetadataResolver MetadataResolver { + get { return metadata_resolver; } + set { metadata_resolver = value; } + } + +#if !READ_ONLY + public IMetadataImporterProvider MetadataImporterProvider { + get { return metadata_importer_provider; } + set { metadata_importer_provider = value; } + } + + public IReflectionImporterProvider ReflectionImporterProvider { + get { return reflection_importer_provider; } + set { reflection_importer_provider = value; } + } +#endif + + public Stream SymbolStream { + get { return symbol_stream; } + set { symbol_stream = value; } + } + + public ISymbolReaderProvider SymbolReaderProvider { + get { return symbol_reader_provider; } + set { symbol_reader_provider = value; } + } + + public bool ReadSymbols { + get { return read_symbols; } + set { read_symbols = value; } + } + + public bool ReadWrite { + get { return read_write; } + set { read_write = value; } + } + + public bool ApplyWindowsRuntimeProjections { + get { return projections; } + set { projections = value; } + } + + public ReaderParameters () + : this (ReadingMode.Deferred) + { + } + + public ReaderParameters (ReadingMode readingMode) + { + this.reading_mode = readingMode; + } + } + +#if !READ_ONLY + + public sealed class ModuleParameters { + + ModuleKind kind; + TargetRuntime runtime; + uint? timestamp; + TargetArchitecture architecture; + IAssemblyResolver assembly_resolver; + IMetadataResolver metadata_resolver; +#if !READ_ONLY + IMetadataImporterProvider metadata_importer_provider; + IReflectionImporterProvider reflection_importer_provider; +#endif + + public ModuleKind Kind { + get { return kind; } + set { kind = value; } + } + + public TargetRuntime Runtime { + get { return runtime; } + set { runtime = value; } + } + + public uint? Timestamp { + get { return timestamp; } + set { timestamp = value; } + } + + public TargetArchitecture Architecture { + get { return architecture; } + set { architecture = value; } + } + + public IAssemblyResolver AssemblyResolver { + get { return assembly_resolver; } + set { assembly_resolver = value; } + } + + public IMetadataResolver MetadataResolver { + get { return metadata_resolver; } + set { metadata_resolver = value; } + } + +#if !READ_ONLY + public IMetadataImporterProvider MetadataImporterProvider { + get { return metadata_importer_provider; } + set { metadata_importer_provider = value; } + } + + public IReflectionImporterProvider ReflectionImporterProvider { + get { return reflection_importer_provider; } + set { reflection_importer_provider = value; } + } +#endif + + public ModuleParameters () + { + this.kind = ModuleKind.Dll; + this.Runtime = GetCurrentRuntime (); + this.architecture = TargetArchitecture.I386; + } + + static TargetRuntime GetCurrentRuntime () + { +#if !NET_CORE + return typeof (object).Assembly.ImageRuntimeVersion.ParseRuntime (); +#else + var corlib_name = AssemblyNameReference.Parse (typeof (object).Assembly ().FullName); + var corlib_version = corlib_name.Version; + + switch (corlib_version.Major) { + case 1: + return corlib_version.Minor == 0 + ? TargetRuntime.Net_1_0 + : TargetRuntime.Net_1_1; + case 2: + return TargetRuntime.Net_2_0; + case 4: + return TargetRuntime.Net_4_0; + default: + throw new NotSupportedException (); + } +#endif + } + } + + public sealed class WriterParameters { + + uint? timestamp; + Stream symbol_stream; + ISymbolWriterProvider symbol_writer_provider; + bool write_symbols; +#if !NET_CORE + SR.StrongNameKeyPair key_pair; +#endif + + public uint? Timestamp { + get { return timestamp; } + set { timestamp = value; } + } + + public Stream SymbolStream { + get { return symbol_stream; } + set { symbol_stream = value; } + } + + public ISymbolWriterProvider SymbolWriterProvider { + get { return symbol_writer_provider; } + set { symbol_writer_provider = value; } + } + + public bool WriteSymbols { + get { return write_symbols; } + set { write_symbols = value; } + } + +#if !NET_CORE + public SR.StrongNameKeyPair StrongNameKeyPair { + get { return key_pair; } + set { key_pair = value; } + } +#endif + } + +#endif + + public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider, ICustomDebugInformationProvider, IDisposable { + + internal Image Image; + internal MetadataSystem MetadataSystem; + internal ReadingMode ReadingMode; + internal ISymbolReaderProvider SymbolReaderProvider; + + internal ISymbolReader symbol_reader; + internal Disposable assembly_resolver; + internal IMetadataResolver metadata_resolver; + internal TypeSystem type_system; + internal readonly MetadataReader reader; + readonly string file_name; + + internal string runtime_version; + internal ModuleKind kind; + WindowsRuntimeProjections projections; + MetadataKind metadata_kind; + TargetRuntime runtime; + TargetArchitecture architecture; + ModuleAttributes attributes; + ModuleCharacteristics characteristics; + Guid mvid; + internal uint timestamp; + + internal AssemblyDefinition assembly; + MethodDefinition entry_point; + +#if !READ_ONLY + internal IReflectionImporter reflection_importer; + internal IMetadataImporter metadata_importer; +#endif + Collection custom_attributes; + Collection references; + Collection modules; + Collection resources; + Collection exported_types; + TypeDefinitionCollection types; + + internal Collection custom_infos; + + public bool IsMain { + get { return kind != ModuleKind.NetModule; } + } + + public ModuleKind Kind { + get { return kind; } + set { kind = value; } + } + + public MetadataKind MetadataKind { + get { return metadata_kind; } + set { metadata_kind = value; } + } + + internal WindowsRuntimeProjections Projections { + get { + if (projections == null) + Interlocked.CompareExchange (ref projections, new WindowsRuntimeProjections (this), null); + + return projections; + } + } + + public TargetRuntime Runtime { + get { return runtime; } + set { + runtime = value; + runtime_version = runtime.RuntimeVersionString (); + } + } + + public string RuntimeVersion { + get { return runtime_version; } + set { + runtime_version = value; + runtime = runtime_version.ParseRuntime (); + } + } + + public TargetArchitecture Architecture { + get { return architecture; } + set { architecture = value; } + } + + public ModuleAttributes Attributes { + get { return attributes; } + set { attributes = value; } + } + + public ModuleCharacteristics Characteristics { + get { return characteristics; } + set { characteristics = value; } + } + + [Obsolete("Use FileName")] + public string FullyQualifiedName { + get { return file_name; } + } + + public string FileName { + get { return file_name; } + } + + public Guid Mvid { + get { return mvid; } + set { mvid = value; } + } + + internal bool HasImage { + get { return Image != null; } + } + + public bool HasSymbols { + get { return symbol_reader != null; } + } + + public ISymbolReader SymbolReader { + get { return symbol_reader; } + } + + public override MetadataScopeType MetadataScopeType { + get { return MetadataScopeType.ModuleDefinition; } + } + + public AssemblyDefinition Assembly { + get { return assembly; } + } + +#if !READ_ONLY + internal IReflectionImporter ReflectionImporter { + get { + if (reflection_importer == null) + Interlocked.CompareExchange (ref reflection_importer, new DefaultReflectionImporter (this), null); + + return reflection_importer; + } + } + + internal IMetadataImporter MetadataImporter { + get { + if (metadata_importer == null) + Interlocked.CompareExchange (ref metadata_importer, new DefaultMetadataImporter (this), null); + + return metadata_importer; + } + } +#endif + + public IAssemblyResolver AssemblyResolver { + get { +#if !NET_CORE + if (assembly_resolver.value == null) { + lock (module_lock) { + assembly_resolver = Disposable.Owned (new DefaultAssemblyResolver () as IAssemblyResolver); + } + } +#endif + + return assembly_resolver.value; + } + } + + public IMetadataResolver MetadataResolver { + get { + if (metadata_resolver == null) + Interlocked.CompareExchange (ref metadata_resolver, new MetadataResolver (this.AssemblyResolver), null); + + return metadata_resolver; + } + } + + public TypeSystem TypeSystem { + get { + if (type_system == null) + Interlocked.CompareExchange (ref type_system, TypeSystem.CreateTypeSystem (this), null); + + return type_system; + } + } + + public bool HasAssemblyReferences { + get { + if (references != null) + return references.Count > 0; + + return HasImage && Image.HasTable (Table.AssemblyRef); + } + } + + public Collection AssemblyReferences { + get { + if (references != null) + return references; + + if (HasImage) + return Read (ref references, this, (_, reader) => reader.ReadAssemblyReferences ()); + + return references = new Collection (); + } + } + + public bool HasModuleReferences { + get { + if (modules != null) + return modules.Count > 0; + + return HasImage && Image.HasTable (Table.ModuleRef); + } + } + + public Collection ModuleReferences { + get { + if (modules != null) + return modules; + + if (HasImage) + return Read (ref modules, this, (_, reader) => reader.ReadModuleReferences ()); + + return modules = new Collection (); + } + } + + public bool HasResources { + get { + if (resources != null) + return resources.Count > 0; + + if (HasImage) + return Image.HasTable (Table.ManifestResource) || Read (this, (_, reader) => reader.HasFileResource ()); + + return false; + } + } + + public Collection Resources { + get { + if (resources != null) + return resources; + + if (HasImage) + return Read (ref resources, this, (_, reader) => reader.ReadResources ()); + + return resources = new Collection (); + } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return this.GetHasCustomAttributes (this); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, this)); } + } + + public bool HasTypes { + get { + if (types != null) + return types.Count > 0; + + return HasImage && Image.HasTable (Table.TypeDef); + } + } + + public Collection Types { + get { + if (types != null) + return types; + + if (HasImage) + return Read (ref types, this, (_, reader) => reader.ReadTypes ()); + + return types = new TypeDefinitionCollection (this); + } + } + + public bool HasExportedTypes { + get { + if (exported_types != null) + return exported_types.Count > 0; + + return HasImage && Image.HasTable (Table.ExportedType); + } + } + + public Collection ExportedTypes { + get { + if (exported_types != null) + return exported_types; + + if (HasImage) + return Read (ref exported_types, this, (_, reader) => reader.ReadExportedTypes ()); + + return exported_types = new Collection (); + } + } + + public MethodDefinition EntryPoint { + get { + if (entry_point != null) + return entry_point; + + if (HasImage) + return Read (ref entry_point, this, (_, reader) => reader.ReadEntryPoint ()); + + return entry_point = null; + } + set { entry_point = value; } + } + + public bool HasCustomDebugInformations { + get { + return custom_infos != null && custom_infos.Count > 0; + } + } + + public Collection CustomDebugInformations { + get { + return custom_infos ?? (custom_infos = new Collection ()); + } + } + + internal ModuleDefinition () + { + this.MetadataSystem = new MetadataSystem (); + this.token = new MetadataToken (TokenType.Module, 1); + } + + internal ModuleDefinition (Image image) + : this () + { + this.Image = image; + this.kind = image.Kind; + this.RuntimeVersion = image.RuntimeVersion; + this.architecture = image.Architecture; + this.attributes = image.Attributes; + this.characteristics = image.Characteristics; + this.file_name = image.FileName; + this.timestamp = image.Timestamp; + + this.reader = new MetadataReader (this); + } + + public void Dispose () + { + if (Image != null) + Image.Dispose (); + + if (symbol_reader != null) + symbol_reader.Dispose (); + + if (assembly_resolver.value != null) + assembly_resolver.Dispose (); + } + + public bool HasTypeReference (string fullName) + { + return HasTypeReference (string.Empty, fullName); + } + + public bool HasTypeReference (string scope, string fullName) + { + Mixin.CheckFullName (fullName); + + if (!HasImage) + return false; + + return GetTypeReference (scope, fullName) != null; + } + + public bool TryGetTypeReference (string fullName, out TypeReference type) + { + return TryGetTypeReference (string.Empty, fullName, out type); + } + + public bool TryGetTypeReference (string scope, string fullName, out TypeReference type) + { + Mixin.CheckFullName (fullName); + + if (!HasImage) { + type = null; + return false; + } + + return (type = GetTypeReference (scope, fullName)) != null; + } + + TypeReference GetTypeReference (string scope, string fullname) + { + return Read (new Row (scope, fullname), (row, reader) => reader.GetTypeReference (row.Col1, row.Col2)); + } + + public IEnumerable GetTypeReferences () + { + if (!HasImage) + return Empty.Array; + + return Read (this, (_, reader) => reader.GetTypeReferences ()); + } + + public IEnumerable GetMemberReferences () + { + if (!HasImage) + return Empty.Array; + + return Read (this, (_, reader) => reader.GetMemberReferences ()); + } + + public IEnumerable GetCustomAttributes () + { + if (!HasImage) + return Empty.Array; + + return Read (this, (_, reader) => reader.GetCustomAttributes ()); + } + + public TypeReference GetType (string fullName, bool runtimeName) + { + return runtimeName + ? TypeParser.ParseType (this, fullName) + : GetType (fullName); + } + + public TypeDefinition GetType (string fullName) + { + Mixin.CheckFullName (fullName); + + var position = fullName.IndexOf ('/'); + if (position > 0) + return GetNestedType (fullName); + + return ((TypeDefinitionCollection) this.Types).GetType (fullName); + } + + public TypeDefinition GetType (string @namespace, string name) + { + Mixin.CheckName (name); + + return ((TypeDefinitionCollection) this.Types).GetType (@namespace ?? string.Empty, name); + } + + public IEnumerable GetTypes () + { + return GetTypes (Types); + } + + static IEnumerable GetTypes (Collection types) + { + for (int i = 0; i < types.Count; i++) { + var type = types [i]; + + yield return type; + + if (!type.HasNestedTypes) + continue; + + foreach (var nested in GetTypes (type.NestedTypes)) + yield return nested; + } + } + + TypeDefinition GetNestedType (string fullname) + { + var names = fullname.Split ('/'); + var type = GetType (names [0]); + + if (type == null) + return null; + + for (int i = 1; i < names.Length; i++) { + var nested_type = type.GetNestedType (names [i]); + if (nested_type == null) + return null; + + type = nested_type; + } + + return type; + } + + internal FieldDefinition Resolve (FieldReference field) + { +#if NET_CORE + if (MetadataResolver == null) + throw new NotSupportedException (); +#endif + return MetadataResolver.Resolve (field); + } + + internal MethodDefinition Resolve (MethodReference method) + { +#if NET_CORE + if (MetadataResolver == null) + throw new NotSupportedException (); +#endif + return MetadataResolver.Resolve (method); + } + + internal TypeDefinition Resolve (TypeReference type) + { +#if NET_CORE + if (MetadataResolver == null) + throw new NotSupportedException (); +#endif + return MetadataResolver.Resolve (type); + } + +#if !READ_ONLY + + static void CheckContext (IGenericParameterProvider context, ModuleDefinition module) + { + if (context == null) + return; + + if (context.Module != module) + throw new ArgumentException (); + } + + [Obsolete ("Use ImportReference", error: false)] + public TypeReference Import (Type type) + { + return ImportReference (type, null); + } + + public TypeReference ImportReference (Type type) + { + return ImportReference (type, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public TypeReference Import (Type type, IGenericParameterProvider context) + { + return ImportReference (type, context); + } + + public TypeReference ImportReference (Type type, IGenericParameterProvider context) + { + Mixin.CheckType (type); + CheckContext (context, this); + + return ReflectionImporter.ImportReference (type, context); + } + + [Obsolete ("Use ImportReference", error: false)] + public FieldReference Import (SR.FieldInfo field) + { + return ImportReference (field, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public FieldReference Import (SR.FieldInfo field, IGenericParameterProvider context) + { + return ImportReference (field, context); + } + + public FieldReference ImportReference (SR.FieldInfo field) + { + return ImportReference (field, null); + } + + public FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context) + { + Mixin.CheckField (field); + CheckContext (context, this); + + return ReflectionImporter.ImportReference (field, context); + } + + [Obsolete ("Use ImportReference", error: false)] + public MethodReference Import (SR.MethodBase method) + { + return ImportReference (method, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public MethodReference Import (SR.MethodBase method, IGenericParameterProvider context) + { + return ImportReference (method, context); + } + + public MethodReference ImportReference (SR.MethodBase method) + { + return ImportReference (method, null); + } + + public MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context) + { + Mixin.CheckMethod (method); + CheckContext (context, this); + + return ReflectionImporter.ImportReference (method, context); + } + + [Obsolete ("Use ImportReference", error: false)] + public TypeReference Import (TypeReference type) + { + return ImportReference (type, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public TypeReference Import (TypeReference type, IGenericParameterProvider context) + { + return ImportReference (type, context); + } + + public TypeReference ImportReference (TypeReference type) + { + return ImportReference (type, null); + } + + public TypeReference ImportReference (TypeReference type, IGenericParameterProvider context) + { + Mixin.CheckType (type); + + if (type.Module == this) + return type; + + CheckContext (context, this); + + return MetadataImporter.ImportReference (type, context); + } + + [Obsolete ("Use ImportReference", error: false)] + public FieldReference Import (FieldReference field) + { + return ImportReference (field, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public FieldReference Import (FieldReference field, IGenericParameterProvider context) + { + return ImportReference (field, context); + } + + public FieldReference ImportReference (FieldReference field) + { + return ImportReference (field, null); + } + + public FieldReference ImportReference (FieldReference field, IGenericParameterProvider context) + { + Mixin.CheckField (field); + + if (field.Module == this) + return field; + + CheckContext (context, this); + + return MetadataImporter.ImportReference (field, context); + } + + [Obsolete ("Use ImportReference", error: false)] + public MethodReference Import (MethodReference method) + { + return ImportReference (method, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public MethodReference Import (MethodReference method, IGenericParameterProvider context) + { + return ImportReference (method, context); + } + + public MethodReference ImportReference (MethodReference method) + { + return ImportReference (method, null); + } + + public MethodReference ImportReference (MethodReference method, IGenericParameterProvider context) + { + Mixin.CheckMethod (method); + + if (method.Module == this) + return method; + + CheckContext (context, this); + + return MetadataImporter.ImportReference (method, context); + } + +#endif + + public IMetadataTokenProvider LookupToken (int token) + { + return LookupToken (new MetadataToken ((uint) token)); + } + + public IMetadataTokenProvider LookupToken (MetadataToken token) + { + return Read (token, (t, reader) => reader.LookupToken (t)); + } + + readonly object module_lock = new object(); + + internal object SyncRoot { + get { return module_lock; } + } + + internal TRet Read (TItem item, Func read) + { + lock (module_lock) { + var position = reader.position; + var context = reader.context; + + var ret = read (item, reader); + + reader.position = position; + reader.context = context; + + return ret; + } + } + + internal TRet Read (ref TRet variable, TItem item, Func read) where TRet : class + { + lock (module_lock) { + if (variable != null) + return variable; + + var position = reader.position; + var context = reader.context; + + var ret = read (item, reader); + + reader.position = position; + reader.context = context; + + return variable = ret; + } + } + + public bool HasDebugHeader { + get { return Image != null && Image.DebugHeader != null; } + } + + public ImageDebugHeader GetDebugHeader () + { + return Image.DebugHeader ?? new ImageDebugHeader (); + } + +#if !READ_ONLY + + public static ModuleDefinition CreateModule (string name, ModuleKind kind) + { + return CreateModule (name, new ModuleParameters { Kind = kind }); + } + + public static ModuleDefinition CreateModule (string name, ModuleParameters parameters) + { + Mixin.CheckName (name); + Mixin.CheckParameters (parameters); + + var module = new ModuleDefinition { + Name = name, + kind = parameters.Kind, + timestamp = parameters.Timestamp ?? Mixin.GetTimestamp (), + Runtime = parameters.Runtime, + architecture = parameters.Architecture, + mvid = Guid.NewGuid (), + Attributes = ModuleAttributes.ILOnly, + Characteristics = (ModuleCharacteristics) 0x8540, + }; + + if (parameters.AssemblyResolver != null) + module.assembly_resolver = Disposable.NotOwned (parameters.AssemblyResolver); + + if (parameters.MetadataResolver != null) + module.metadata_resolver = parameters.MetadataResolver; + +#if !READ_ONLY + if (parameters.MetadataImporterProvider != null) + module.metadata_importer = parameters.MetadataImporterProvider.GetMetadataImporter (module); + if (parameters.ReflectionImporterProvider != null) + module.reflection_importer = parameters.ReflectionImporterProvider.GetReflectionImporter (module); +#endif + + if (parameters.Kind != ModuleKind.NetModule) { + var assembly = new AssemblyDefinition (); + module.assembly = assembly; + module.assembly.Name = CreateAssemblyName (name); + assembly.main_module = module; + } + + module.Types.Add (new TypeDefinition (string.Empty, "", TypeAttributes.NotPublic)); + + return module; + } + + static AssemblyNameDefinition CreateAssemblyName (string name) + { + if (name.EndsWith (".dll") || name.EndsWith (".exe")) + name = name.Substring (0, name.Length - 4); + + return new AssemblyNameDefinition (name, Mixin.ZeroVersion); + } + +#endif + + public void ReadSymbols () + { + if (string.IsNullOrEmpty (file_name)) + throw new InvalidOperationException (); + + var provider = new DefaultSymbolReaderProvider (throwIfNoSymbol: true); + ReadSymbols (provider.GetSymbolReader (this, file_name)); + } + + public void ReadSymbols (ISymbolReader reader) + { + if (reader == null) + throw new ArgumentNullException ("reader"); + + symbol_reader = reader; + + if (!symbol_reader.ProcessDebugHeader (GetDebugHeader ())) { + symbol_reader = null; + throw new InvalidOperationException (); + } + + if (HasImage && ReadingMode == ReadingMode.Immediate) { + var immediate_reader = new ImmediateModuleReader (Image); + immediate_reader.ReadSymbols (this); + } + } + + public static ModuleDefinition ReadModule (string fileName) + { + return ReadModule (fileName, new ReaderParameters (ReadingMode.Deferred)); + } + + public static ModuleDefinition ReadModule (string fileName, ReaderParameters parameters) + { + var stream = GetFileStream (fileName, FileMode.Open, parameters.ReadWrite ? FileAccess.ReadWrite : FileAccess.Read, FileShare.Read); + + if (parameters.InMemory) { + var memory = new MemoryStream (stream.CanSeek ? (int) stream.Length : 0); + using (stream) + stream.CopyTo (memory); + + memory.Position = 0; + stream = memory; + } + + try { + return ReadModule (Disposable.Owned (stream), fileName, parameters); + } catch (Exception) { + stream.Dispose (); + throw; + } + } + + static Stream GetFileStream (string fileName, FileMode mode, FileAccess access, FileShare share) + { + Mixin.CheckFileName (fileName); + + return new FileStream (fileName, mode, access, share); + } + + public static ModuleDefinition ReadModule (Stream stream) + { + return ReadModule (stream, new ReaderParameters (ReadingMode.Deferred)); + } + + public static ModuleDefinition ReadModule (Stream stream, ReaderParameters parameters) + { + Mixin.CheckStream (stream); + Mixin.CheckReadSeek (stream); + + return ReadModule (Disposable.NotOwned (stream), stream.GetFileName (), parameters); + } + + static ModuleDefinition ReadModule (Disposable stream, string fileName, ReaderParameters parameters) + { + Mixin.CheckParameters (parameters); + + return ModuleReader.CreateModule ( + ImageReader.ReadImage (stream, fileName), + parameters); + } + +#if !READ_ONLY + + public void Write (string fileName) + { + Write (fileName, new WriterParameters ()); + } + + public void Write (string fileName, WriterParameters parameters) + { + Mixin.CheckParameters (parameters); + var file = GetFileStream (fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); + ModuleWriter.WriteModule (this, Disposable.Owned (file), parameters); + } + + public void Write () + { + Write (new WriterParameters ()); + } + + public void Write (WriterParameters parameters) + { + if (!HasImage) + throw new InvalidOperationException (); + + Write (Image.Stream.value, parameters); + } + + public void Write (Stream stream) + { + Write (stream, new WriterParameters ()); + } + + public void Write (Stream stream, WriterParameters parameters) + { + Mixin.CheckStream (stream); + Mixin.CheckWriteSeek (stream); + Mixin.CheckParameters (parameters); + + ModuleWriter.WriteModule (this, Disposable.NotOwned (stream), parameters); + } + +#endif + + } + + static partial class Mixin { + + public enum Argument { + name, + fileName, + fullName, + stream, + type, + method, + field, + parameters, + module, + modifierType, + eventType, + fieldType, + declaringType, + returnType, + propertyType, + interfaceType, + } + + public static void CheckName (object name) + { + if (name == null) + throw new ArgumentNullException (Argument.name.ToString ()); + } + + public static void CheckName (string name) + { + if (string.IsNullOrEmpty (name)) + throw new ArgumentNullOrEmptyException (Argument.name.ToString ()); + } + + public static void CheckFileName (string fileName) + { + if (string.IsNullOrEmpty (fileName)) + throw new ArgumentNullOrEmptyException (Argument.fileName.ToString ()); + } + + public static void CheckFullName (string fullName) + { + if (string.IsNullOrEmpty (fullName)) + throw new ArgumentNullOrEmptyException (Argument.fullName.ToString ()); + } + + public static void CheckStream (object stream) + { + if (stream == null) + throw new ArgumentNullException (Argument.stream.ToString ()); + } + + public static void CheckWriteSeek (Stream stream) + { + if (!stream.CanWrite || !stream.CanSeek) + throw new ArgumentException ("Stream must be writable and seekable."); + } + + public static void CheckReadSeek (Stream stream) + { + if (!stream.CanRead || !stream.CanSeek) + throw new ArgumentException ("Stream must be readable and seekable."); + } + + public static void CheckType (object type) + { + if (type == null) + throw new ArgumentNullException (Argument.type.ToString ()); + } + + public static void CheckType (object type, Argument argument) + { + if (type == null) + throw new ArgumentNullException (argument.ToString ()); + } + + public static void CheckField (object field) + { + if (field == null) + throw new ArgumentNullException (Argument.field.ToString ()); + } + + public static void CheckMethod (object method) + { + if (method == null) + throw new ArgumentNullException (Argument.method.ToString ()); + } + + public static void CheckParameters (object parameters) + { + if (parameters == null) + throw new ArgumentNullException (Argument.parameters.ToString ()); + } + + public static uint GetTimestamp () + { + return (uint) DateTime.UtcNow.Subtract (new DateTime (1970, 1, 1)).TotalSeconds; + } + + public static bool HasImage (this ModuleDefinition self) + { + return self != null && self.HasImage; + } + + public static string GetFileName (this Stream self) + { + var file_stream = self as FileStream; + if (file_stream == null) + return string.Empty; + + return Path.GetFullPath (file_stream.Name); + } + +#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]) { + case '1': + return self [3] == '0' + ? TargetRuntime.Net_1_0 + : TargetRuntime.Net_1_1; + case '2': + return TargetRuntime.Net_2_0; + case '4': + default: + return TargetRuntime.Net_4_0; + } + } + + public static string RuntimeVersionString (this TargetRuntime runtime) + { + switch (runtime) { + case TargetRuntime.Net_1_0: + return "v1.0.3705"; + case TargetRuntime.Net_1_1: + return "v1.1.4322"; + case TargetRuntime.Net_2_0: + return "v2.0.50727"; + case TargetRuntime.Net_4_0: + default: + return "v4.0.30319"; + } + } + + public static bool IsWindowsMetadata (this ModuleDefinition module) + { + return module.MetadataKind != MetadataKind.Ecma335; + } + + 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.ToArray (); + } + + public static void Read (object o) + { + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/ModuleKind.cs b/Mono.Cecil.20/Mono.Cecil/ModuleKind.cs new file mode 100644 index 00000000..a5aa2274 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/ModuleKind.cs @@ -0,0 +1,54 @@ +// +// 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; + +namespace Mono.Cecil { + + public enum ModuleKind { + Dll, + Console, + Windows, + NetModule, + } + + public enum MetadataKind { + Ecma335, + WindowsMetadata, + ManagedWindowsMetadata, + } + + public enum TargetArchitecture { + I386 = 0x014c, + AMD64 = 0x8664, + IA64 = 0x0200, + ARM = 0x01c0, + ARMv7 = 0x01c4, + ARM64 = 0xaa64, + } + + [Flags] + public enum ModuleAttributes { + ILOnly = 1, + Required32Bit = 2, + StrongNameSigned = 8, + Preferred32Bit = 0x00020000, + } + + [Flags] + public enum ModuleCharacteristics { + HighEntropyVA = 0x0020, + DynamicBase = 0x0040, + NoSEH = 0x0400, + NXCompat = 0x0100, + AppContainer = 0x1000, + TerminalServerAware = 0x8000, + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/ModuleReference.cs b/Mono.Cecil.20/Mono.Cecil/ModuleReference.cs new file mode 100644 index 00000000..43c618f4 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/ModuleReference.cs @@ -0,0 +1,49 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public class ModuleReference : IMetadataScope { + + string name; + + internal MetadataToken token; + + public string Name { + get { return name; } + set { name = value; } + } + + public virtual MetadataScopeType MetadataScopeType { + get { return MetadataScopeType.ModuleReference; } + } + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + internal ModuleReference () + { + this.token = new MetadataToken (TokenType.ModuleRef); + } + + public ModuleReference (string name) + : this () + { + this.name = name; + } + + public override string ToString () + { + return name; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/NativeType.cs b/Mono.Cecil.20/Mono.Cecil/NativeType.cs new file mode 100644 index 00000000..02174db6 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/NativeType.cs @@ -0,0 +1,55 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum NativeType { + None = 0x66, + + Boolean = 0x02, + I1 = 0x03, + U1 = 0x04, + I2 = 0x05, + U2 = 0x06, + I4 = 0x07, + U4 = 0x08, + I8 = 0x09, + U8 = 0x0a, + R4 = 0x0b, + R8 = 0x0c, + LPStr = 0x14, + Int = 0x1f, + UInt = 0x20, + Func = 0x26, + Array = 0x2a, + + // Msft specific + Currency = 0x0f, + BStr = 0x13, + LPWStr = 0x15, + LPTStr = 0x16, + FixedSysString = 0x17, + IUnknown = 0x19, + IDispatch = 0x1a, + Struct = 0x1b, + IntF = 0x1c, + SafeArray = 0x1d, + FixedArray = 0x1e, + ByValStr = 0x22, + ANSIBStr = 0x23, + TBStr = 0x24, + VariantBool = 0x25, + ASAny = 0x28, + LPStruct = 0x2b, + CustomMarshaler = 0x2c, + Error = 0x2d, + Max = 0x50 + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/PInvokeAttributes.cs b/Mono.Cecil.20/Mono.Cecil/PInvokeAttributes.cs new file mode 100644 index 00000000..11e96d20 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/PInvokeAttributes.cs @@ -0,0 +1,44 @@ +// +// 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; + +namespace Mono.Cecil { + + [Flags] + public enum PInvokeAttributes : ushort { + NoMangle = 0x0001, // PInvoke is to use the member name as specified + + // Character set + CharSetMask = 0x0006, + CharSetNotSpec = 0x0000, + CharSetAnsi = 0x0002, + CharSetUnicode = 0x0004, + CharSetAuto = 0x0006, + + SupportsLastError = 0x0040, // Information about target function. Not relevant for fields + + // Calling convetion + CallConvMask = 0x0700, + CallConvWinapi = 0x0100, + CallConvCdecl = 0x0200, + CallConvStdCall = 0x0300, + CallConvThiscall = 0x0400, + CallConvFastcall = 0x0500, + + BestFitMask = 0x0030, + BestFitEnabled = 0x0010, + BestFitDisabled = 0x0020, + + ThrowOnUnmappableCharMask = 0x3000, + ThrowOnUnmappableCharEnabled = 0x1000, + ThrowOnUnmappableCharDisabled = 0x2000, + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/PInvokeInfo.cs b/Mono.Cecil.20/Mono.Cecil/PInvokeInfo.cs new file mode 100644 index 00000000..8efc0108 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/PInvokeInfo.cs @@ -0,0 +1,120 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public sealed class PInvokeInfo { + + ushort attributes; + string entry_point; + ModuleReference module; + + public PInvokeAttributes Attributes { + get { return (PInvokeAttributes) attributes; } + set { attributes = (ushort) value; } + } + + public string EntryPoint { + get { return entry_point; } + set { entry_point = value; } + } + + public ModuleReference Module { + get { return module; } + set { module = value; } + } + + #region PInvokeAttributes + + public bool IsNoMangle { + get { return attributes.GetAttributes ((ushort) PInvokeAttributes.NoMangle); } + set { attributes = attributes.SetAttributes ((ushort) PInvokeAttributes.NoMangle, value); } + } + + public bool IsCharSetNotSpec { + get { return attributes.GetMaskedAttributes((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec, value); } + } + + public bool IsCharSetAnsi { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi, value); } + } + + public bool IsCharSetUnicode { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode, value); } + } + + public bool IsCharSetAuto { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto, value); } + } + + public bool SupportsLastError { + get { return attributes.GetAttributes ((ushort) PInvokeAttributes.SupportsLastError); } + set { attributes = attributes.SetAttributes ((ushort) PInvokeAttributes.SupportsLastError, value); } + } + + public bool IsCallConvWinapi { + get { return attributes.GetMaskedAttributes((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi, value); } + } + + public bool IsCallConvCdecl { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl, value); } + } + + public bool IsCallConvStdCall { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall, value); } + } + + public bool IsCallConvThiscall { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall, value); } + } + + public bool IsCallConvFastcall { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall, value); } + } + + public bool IsBestFitEnabled { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled, value); } + } + + public bool IsBestFitDisabled { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled, value); } + } + + public bool IsThrowOnUnmappableCharEnabled { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled, value); } + } + + public bool IsThrowOnUnmappableCharDisabled { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharDisabled); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharDisabled, value); } + } + + #endregion + + public PInvokeInfo (PInvokeAttributes attributes, string entryPoint, ModuleReference module) + { + this.attributes = (ushort) attributes; + this.entry_point = entryPoint; + this.module = module; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/ParameterAttributes.cs b/Mono.Cecil.20/Mono.Cecil/ParameterAttributes.cs new file mode 100644 index 00000000..9a0e35e0 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/ParameterAttributes.cs @@ -0,0 +1,27 @@ +// +// 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; + +namespace Mono.Cecil { + + [Flags] + public enum ParameterAttributes : ushort { + None = 0x0000, + In = 0x0001, // Param is [In] + Out = 0x0002, // Param is [Out] + Lcid = 0x0004, + Retval = 0x0008, + Optional = 0x0010, // Param is optional + HasDefault = 0x1000, // Param has default value + HasFieldMarshal = 0x2000, // Param has field marshal + Unused = 0xcfe0 // Reserved: shall be zero in a conforming implementation + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/ParameterDefinition.cs b/Mono.Cecil.20/Mono.Cecil/ParameterDefinition.cs new file mode 100644 index 00000000..59bafe2c --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/ParameterDefinition.cs @@ -0,0 +1,146 @@ +// +// 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.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class ParameterDefinition : ParameterReference, ICustomAttributeProvider, IConstantProvider, IMarshalInfoProvider { + + ushort attributes; + + internal IMethodSignature method; + + object constant = Mixin.NotResolved; + Collection custom_attributes; + MarshalInfo marshal_info; + + public ParameterAttributes Attributes { + get { return (ParameterAttributes) attributes; } + set { attributes = (ushort) value; } + } + + public IMethodSignature Method { + get { return method; } + } + + public int Sequence { + get { + if (method == null) + return -1; + + return method.HasImplicitThis () ? index + 1 : index; + } + } + + public bool HasConstant { + get { + this.ResolveConstant (ref constant, parameter_type.Module); + + return constant != Mixin.NoValue; + } + set { if (!value) constant = Mixin.NoValue; } + } + + public object Constant { + get { return HasConstant ? constant : null; } + set { constant = value; } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return this.GetHasCustomAttributes (parameter_type.Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, parameter_type.Module)); } + } + + public bool HasMarshalInfo { + get { + if (marshal_info != null) + return true; + + return this.GetHasMarshalInfo (parameter_type.Module); + } + } + + public MarshalInfo MarshalInfo { + get { return marshal_info ?? (this.GetMarshalInfo (ref marshal_info, parameter_type.Module)); } + set { marshal_info = value; } + } + + #region ParameterAttributes + + public bool IsIn { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.In); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.In, value); } + } + + public bool IsOut { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.Out); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Out, value); } + } + + public bool IsLcid { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.Lcid); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Lcid, value); } + } + + public bool IsReturnValue { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.Retval); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Retval, value); } + } + + public bool IsOptional { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.Optional); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Optional, value); } + } + + public bool HasDefault { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.HasDefault); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.HasDefault, value); } + } + + public bool HasFieldMarshal { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.HasFieldMarshal); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.HasFieldMarshal, value); } + } + + #endregion + + internal ParameterDefinition (TypeReference parameterType, IMethodSignature method) + : this (string.Empty, ParameterAttributes.None, parameterType) + { + this.method = method; + } + + public ParameterDefinition (TypeReference parameterType) + : this (string.Empty, ParameterAttributes.None, parameterType) + { + } + + public ParameterDefinition (string name, ParameterAttributes attributes, TypeReference parameterType) + : base (name, parameterType) + { + this.attributes = (ushort) attributes; + this.token = new MetadataToken (TokenType.Param); + } + + public override ParameterDefinition Resolve () + { + return this; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/ParameterDefinitionCollection.cs b/Mono.Cecil.20/Mono.Cecil/ParameterDefinitionCollection.cs new file mode 100644 index 00000000..1a9764c5 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/ParameterDefinitionCollection.cs @@ -0,0 +1,62 @@ +// +// 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 Mono.Collections.Generic; + +namespace Mono.Cecil { + + sealed class ParameterDefinitionCollection : Collection { + + readonly IMethodSignature method; + + internal ParameterDefinitionCollection (IMethodSignature method) + { + this.method = method; + } + + internal ParameterDefinitionCollection (IMethodSignature method, int capacity) + : base (capacity) + { + this.method = method; + } + + protected override void OnAdd (ParameterDefinition item, int index) + { + item.method = method; + item.index = index; + } + + protected override void OnInsert (ParameterDefinition item, int index) + { + item.method = method; + item.index = index; + + for (int i = index; i < size; i++) + items [i].index = i + 1; + } + + protected override void OnSet (ParameterDefinition item, int index) + { + item.method = method; + item.index = index; + } + + protected override void OnRemove (ParameterDefinition item, int index) + { + item.method = null; + item.index = -1; + + for (int i = index + 1; i < size; i++) + items [i].index = i - 1; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/ParameterReference.cs b/Mono.Cecil.20/Mono.Cecil/ParameterReference.cs new file mode 100644 index 00000000..4670a562 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/ParameterReference.cs @@ -0,0 +1,57 @@ +// +// 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; + +namespace Mono.Cecil { + + public abstract class ParameterReference : IMetadataTokenProvider { + + string name; + internal int index = -1; + protected TypeReference parameter_type; + internal MetadataToken token; + + public string Name { + get { return name; } + set { name = value; } + } + + public int Index { + get { return index; } + } + + public TypeReference ParameterType { + get { return parameter_type; } + set { parameter_type = value; } + } + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + internal ParameterReference (string name, TypeReference parameterType) + { + if (parameterType == null) + throw new ArgumentNullException ("parameterType"); + + this.name = name ?? string.Empty; + this.parameter_type = parameterType; + } + + public override string ToString () + { + return name; + } + + public abstract ParameterDefinition Resolve (); + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/PinnedType.cs b/Mono.Cecil.20/Mono.Cecil/PinnedType.cs new file mode 100644 index 00000000..fa89af51 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/PinnedType.cs @@ -0,0 +1,35 @@ +// +// 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 MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public sealed class PinnedType : TypeSpecification { + + public override bool IsValueType { + get { return false; } + set { throw new InvalidOperationException (); } + } + + public override bool IsPinned { + get { return true; } + } + + public PinnedType (TypeReference type) + : base (type) + { + Mixin.CheckType (type); + this.etype = MD.ElementType.Pinned; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/PointerType.cs b/Mono.Cecil.20/Mono.Cecil/PointerType.cs new file mode 100644 index 00000000..4b21164a --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/PointerType.cs @@ -0,0 +1,43 @@ +// +// 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 MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public sealed class PointerType : TypeSpecification { + + public override string Name { + get { return base.Name + "*"; } + } + + public override string FullName { + get { return base.FullName + "*"; } + } + + public override bool IsValueType { + get { return false; } + set { throw new InvalidOperationException (); } + } + + public override bool IsPointer { + get { return true; } + } + + public PointerType (TypeReference type) + : base (type) + { + Mixin.CheckType (type); + this.etype = MD.ElementType.Ptr; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/PropertyAttributes.cs b/Mono.Cecil.20/Mono.Cecil/PropertyAttributes.cs new file mode 100644 index 00000000..4d1ce8c8 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/PropertyAttributes.cs @@ -0,0 +1,23 @@ +// +// 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; + +namespace Mono.Cecil { + + [Flags] + public enum PropertyAttributes : ushort { + None = 0x0000, + SpecialName = 0x0200, // Property is special + RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding + HasDefault = 0x1000, // Property has default + Unused = 0xe9ff // Reserved: shall be zero in a conforming implementation + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyDefinition.cs b/Mono.Cecil.20/Mono.Cecil/PropertyDefinition.cs similarity index 68% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyDefinition.cs rename to Mono.Cecil.20/Mono.Cecil/PropertyDefinition.cs index 7435ab49..87f29475 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyDefinition.cs +++ b/Mono.Cecil.20/Mono.Cecil/PropertyDefinition.cs @@ -1,29 +1,11 @@ // -// PropertyDefinition.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System.Text; @@ -71,12 +53,12 @@ public bool HasCustomAttributes { if (custom_attributes != null) return custom_attributes.Count > 0; - return Mixin.GetHasCustomAttributes(this, Module); + return this.GetHasCustomAttributes (Module); } } public Collection CustomAttributes { - get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } } public MethodDefinition GetMethod { @@ -107,7 +89,7 @@ public bool HasOtherMethods { return other_methods.Count > 0; InitializeMethods (); - return !Mixin.IsNullOrEmpty (other_methods); + return !other_methods.IsNullOrEmpty (); } } @@ -170,7 +152,7 @@ static Collection MirrorParameters (MethodDefinition method public bool HasConstant { get { - Mixin.ResolveConstant(this, ref constant, Module); + this.ResolveConstant (ref constant, Module); return constant != Mixin.NoValue; } @@ -185,18 +167,18 @@ public object Constant { #region PropertyAttributes public bool IsSpecialName { - get { return Mixin.GetAttributes(attributes,(ushort) PropertyAttributes.SpecialName); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) PropertyAttributes.SpecialName, value); } + get { return attributes.GetAttributes ((ushort) PropertyAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((ushort) PropertyAttributes.SpecialName, value); } } public bool IsRuntimeSpecialName { - get { return Mixin.GetAttributes(attributes,(ushort) PropertyAttributes.RTSpecialName); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) PropertyAttributes.RTSpecialName, value); } + get { return attributes.GetAttributes ((ushort) PropertyAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((ushort) PropertyAttributes.RTSpecialName, value); } } public bool HasDefault { - get { return Mixin.GetAttributes(attributes,(ushort) PropertyAttributes.HasDefault); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) PropertyAttributes.HasDefault, value); } + get { return attributes.GetAttributes ((ushort) PropertyAttributes.HasDefault); } + set { attributes = attributes.SetAttributes ((ushort) PropertyAttributes.HasDefault, value); } } #endregion @@ -240,11 +222,14 @@ public PropertyDefinition (string name, PropertyAttributes attributes, TypeRefer void InitializeMethods () { var module = this.Module; + if (module == null) + return; + lock (module.SyncRoot) { if (get_method != null || set_method != null) return; - if (!Mixin.HasImage(module)) + if (!module.HasImage ()) return; module.Read (this, (property, reader) => reader.ReadMethods (property)); diff --git a/Mono.Cecil.20/Mono.Cecil/PropertyReference.cs b/Mono.Cecil.20/Mono.Cecil/PropertyReference.cs new file mode 100644 index 00000000..2434d0f8 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/PropertyReference.cs @@ -0,0 +1,45 @@ +// +// 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 Mono.Collections.Generic; + +namespace Mono.Cecil { + + public abstract class PropertyReference : MemberReference { + + TypeReference property_type; + + public TypeReference PropertyType { + get { return property_type; } + set { property_type = value; } + } + + public abstract Collection Parameters { + get; + } + + internal PropertyReference (string name, TypeReference propertyType) + : base (name) + { + Mixin.CheckType (propertyType, Mixin.Argument.propertyType); + + property_type = propertyType; + } + + protected override IMemberDefinition ResolveDefinition () + { + return this.Resolve (); + } + + public new abstract PropertyDefinition Resolve (); + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/ReferenceType.cs b/Mono.Cecil.20/Mono.Cecil/ReferenceType.cs new file mode 100644 index 00000000..67686fbf --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/ReferenceType.cs @@ -0,0 +1,43 @@ +// +// 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 MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public sealed class ByReferenceType : TypeSpecification { + + public override string Name { + get { return base.Name + "&"; } + } + + public override string FullName { + get { return base.FullName + "&"; } + } + + public override bool IsValueType { + get { return false; } + set { throw new InvalidOperationException (); } + } + + public override bool IsByReference { + get { return true; } + } + + public ByReferenceType (TypeReference type) + : base (type) + { + Mixin.CheckType (type); + this.etype = MD.ElementType.ByRef; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/Resource.cs b/Mono.Cecil.20/Mono.Cecil/Resource.cs new file mode 100644 index 00000000..cee75f9e --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/Resource.cs @@ -0,0 +1,58 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum ResourceType { + Linked, + Embedded, + AssemblyLinked, + } + + public abstract class Resource { + + string name; + uint attributes; + + public string Name { + get { return name; } + set { name = value; } + } + + public ManifestResourceAttributes Attributes { + get { return (ManifestResourceAttributes) attributes; } + set { attributes = (uint) value; } + } + + public abstract ResourceType ResourceType { + get; + } + + #region ManifestResourceAttributes + + public bool IsPublic { + get { return attributes.GetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public); } + set { attributes = attributes.SetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public, value); } + } + + public bool IsPrivate { + get { return attributes.GetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private); } + set { attributes = attributes.SetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private, value); } + } + + #endregion + + internal Resource (string name, ManifestResourceAttributes attributes) + { + this.name = name; + this.attributes = (uint) attributes; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/SecurityDeclaration.cs b/Mono.Cecil.20/Mono.Cecil/SecurityDeclaration.cs new file mode 100644 index 00000000..309f7d21 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/SecurityDeclaration.cs @@ -0,0 +1,174 @@ +// +// 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 Mono.Collections.Generic; + +namespace Mono.Cecil { + + public enum SecurityAction : ushort { + Request = 1, + Demand = 2, + Assert = 3, + Deny = 4, + PermitOnly = 5, + LinkDemand = 6, + InheritDemand = 7, + RequestMinimum = 8, + RequestOptional = 9, + RequestRefuse = 10, + PreJitGrant = 11, + PreJitDeny = 12, + NonCasDemand = 13, + NonCasLinkDemand = 14, + NonCasInheritance = 15 + } + + public interface ISecurityDeclarationProvider : IMetadataTokenProvider { + + bool HasSecurityDeclarations { get; } + Collection SecurityDeclarations { get; } + } + + public sealed class SecurityAttribute : ICustomAttribute { + + TypeReference attribute_type; + + internal Collection fields; + internal Collection properties; + + public TypeReference AttributeType { + get { return attribute_type; } + set { attribute_type = value; } + } + + public bool HasFields { + get { return !fields.IsNullOrEmpty (); } + } + + public Collection Fields { + get { return fields ?? (fields = new Collection ()); } + } + + public bool HasProperties { + get { return !properties.IsNullOrEmpty (); } + } + + public Collection Properties { + get { return properties ?? (properties = new Collection ()); } + } + + public SecurityAttribute (TypeReference attributeType) + { + this.attribute_type = attributeType; + } + } + + public sealed class SecurityDeclaration { + + readonly internal uint signature; + byte [] blob; + readonly ModuleDefinition module; + + internal bool resolved; + SecurityAction action; + internal Collection security_attributes; + + public SecurityAction Action { + get { return action; } + set { action = value; } + } + + public bool HasSecurityAttributes { + get { + Resolve (); + + return !security_attributes.IsNullOrEmpty (); + } + } + + public Collection SecurityAttributes { + get { + Resolve (); + + return security_attributes ?? (security_attributes = new Collection ()); + } + } + + internal bool HasImage { + get { return module != null && module.HasImage; } + } + + internal SecurityDeclaration (SecurityAction action, uint signature, ModuleDefinition module) + { + this.action = action; + this.signature = signature; + this.module = module; + } + + public SecurityDeclaration (SecurityAction action) + { + this.action = action; + this.resolved = true; + } + + public SecurityDeclaration (SecurityAction action, byte [] blob) + { + this.action = action; + this.resolved = false; + this.blob = blob; + } + + public byte [] GetBlob () + { + if (blob != null) + return blob; + + if (!HasImage || signature == 0) + throw new NotSupportedException (); + + return blob = module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationBlob (declaration.signature)); + } + + void Resolve () + { + if (resolved || !HasImage) + return; + + module.Read (this, (declaration, reader) => { + reader.ReadSecurityDeclarationSignature (declaration); + return this; + }); + + resolved = true; + } + } + + static partial class Mixin { + + public static bool GetHasSecurityDeclarations ( + this ISecurityDeclarationProvider self, + ModuleDefinition module) + { + return module.HasImage () && module.Read (self, (provider, reader) => reader.HasSecurityDeclarations (provider)); + } + + public static Collection GetSecurityDeclarations ( + this ISecurityDeclarationProvider self, + ref Collection variable, + ModuleDefinition module) + { + return module.HasImage () + ? module.Read (ref variable, self, (provider, reader) => reader.ReadSecurityDeclarations (provider)) + : variable = new Collection(); + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/SentinelType.cs b/Mono.Cecil.20/Mono.Cecil/SentinelType.cs new file mode 100644 index 00000000..b603cc3c --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/SentinelType.cs @@ -0,0 +1,35 @@ +// +// 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 MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public sealed class SentinelType : TypeSpecification { + + public override bool IsValueType { + get { return false; } + set { throw new InvalidOperationException (); } + } + + public override bool IsSentinel { + get { return true; } + } + + public SentinelType (TypeReference type) + : base (type) + { + Mixin.CheckType (type); + this.etype = MD.ElementType.Sentinel; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/TargetRuntime.cs b/Mono.Cecil.20/Mono.Cecil/TargetRuntime.cs new file mode 100644 index 00000000..c1cd0269 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/TargetRuntime.cs @@ -0,0 +1,19 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum TargetRuntime { + Net_1_0, + Net_1_1, + Net_2_0, + Net_4_0, + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/Treatments.cs b/Mono.Cecil.20/Mono.Cecil/Treatments.cs new file mode 100644 index 00000000..4ceaebf7 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/Treatments.cs @@ -0,0 +1,66 @@ +// +// 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; + +namespace Mono.Cecil { + + [Flags] + enum TypeDefinitionTreatment { + None = 0x0, + + KindMask = 0xf, + NormalType = 0x1, + NormalAttribute = 0x2, + UnmangleWindowsRuntimeName = 0x3, + PrefixWindowsRuntimeName = 0x4, + RedirectToClrType = 0x5, + RedirectToClrAttribute = 0x6, + + Abstract = 0x10, + Internal = 0x20, + } + + enum TypeReferenceTreatment { + None = 0x0, + SystemDelegate = 0x1, + SystemAttribute = 0x2, + UseProjectionInfo = 0x3, + } + + [Flags] + enum MethodDefinitionTreatment { + None = 0x0, + Dispose = 0x1, + Abstract = 0x2, + Private = 0x4, + Public = 0x8, + Runtime = 0x10, + InternalCall = 0x20, + } + + enum FieldDefinitionTreatment { + None = 0x0, + Public = 0x1, + } + + enum MemberReferenceTreatment { + None = 0x0, + Dispose = 0x1, + } + + enum CustomAttributeValueTreatment { + None = 0x0, + AllowSingle = 0x1, + AllowMultiple = 0x2, + VersionAttribute = 0x3, + DeprecatedAttribute = 0x4, + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeAttributes.cs b/Mono.Cecil.20/Mono.Cecil/TypeAttributes.cs similarity index 68% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeAttributes.cs rename to Mono.Cecil.20/Mono.Cecil/TypeAttributes.cs index 86fbc4db..92a71aca 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeAttributes.cs +++ b/Mono.Cecil.20/Mono.Cecil/TypeAttributes.cs @@ -1,29 +1,11 @@ // -// TypeAttributes.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; diff --git a/Mono.Cecil.20/Mono.Cecil/TypeDefinition.cs b/Mono.Cecil.20/Mono.Cecil/TypeDefinition.cs new file mode 100644 index 00000000..3e4928ce --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/TypeDefinition.cs @@ -0,0 +1,606 @@ +// +// 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 Mono.Cecil.Metadata; +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class TypeDefinition : TypeReference, IMemberDefinition, ISecurityDeclarationProvider { + + uint attributes; + TypeReference base_type; + internal Range fields_range; + internal Range methods_range; + + short packing_size = Mixin.NotResolvedMarker; + int class_size = Mixin.NotResolvedMarker; + + InterfaceImplementationCollection interfaces; + Collection nested_types; + Collection methods; + Collection fields; + Collection events; + Collection properties; + Collection custom_attributes; + Collection security_declarations; + + public TypeAttributes Attributes { + get { return (TypeAttributes) attributes; } + set { + if (IsWindowsRuntimeProjection && (ushort) value != attributes) + throw new InvalidOperationException (); + + attributes = (uint) value; + } + } + + public TypeReference BaseType { + get { return base_type; } + set { base_type = value; } + } + + public override string Name { + get { return base.Name; } + set { + if (IsWindowsRuntimeProjection && value != base.Name) + throw new InvalidOperationException (); + + base.Name = value; + } + } + + void ResolveLayout () + { + if (packing_size != Mixin.NotResolvedMarker || class_size != Mixin.NotResolvedMarker) + return; + + if (!HasImage) { + packing_size = Mixin.NoDataMarker; + class_size = Mixin.NoDataMarker; + return; + } + + var row = Module.Read (this, (type, reader) => reader.ReadTypeLayout (type)); + + packing_size = row.Col1; + class_size = row.Col2; + } + + public bool HasLayoutInfo { + get { + if (packing_size >= 0 || class_size >= 0) + return true; + + ResolveLayout (); + + return packing_size >= 0 || class_size >= 0; + } + } + + public short PackingSize { + get { + if (packing_size >= 0) + return packing_size; + + ResolveLayout (); + + return packing_size >= 0 ? packing_size : (short) -1; + } + set { packing_size = value; } + } + + public int ClassSize { + get { + if (class_size >= 0) + return class_size; + + ResolveLayout (); + + return class_size >= 0 ? class_size : -1; + } + set { class_size = value; } + } + + public bool HasInterfaces { + get { + if (interfaces != null) + return interfaces.Count > 0; + + return HasImage && Module.Read (this, (type, reader) => reader.HasInterfaces (type)); + } + } + + public Collection Interfaces { + get { + if (interfaces != null) + return interfaces; + + if (HasImage) + return Module.Read (ref interfaces, this, (type, reader) => reader.ReadInterfaces (type)); + + return interfaces = new InterfaceImplementationCollection (this); + } + } + + public bool HasNestedTypes { + get { + if (nested_types != null) + return nested_types.Count > 0; + + return HasImage && Module.Read (this, (type, reader) => reader.HasNestedTypes (type)); + } + } + + public Collection NestedTypes { + get { + if (nested_types != null) + return nested_types; + + if (HasImage) + return Module.Read (ref nested_types, this, (type, reader) => reader.ReadNestedTypes (type)); + + return nested_types = new MemberDefinitionCollection (this); + } + } + + public bool HasMethods { + get { + if (methods != null) + return methods.Count > 0; + + return HasImage && methods_range.Length > 0; + } + } + + public Collection Methods { + get { + if (methods != null) + return methods; + + if (HasImage) + return Module.Read (ref methods, this, (type, reader) => reader.ReadMethods (type)); + + return methods = new MemberDefinitionCollection (this); + } + } + + public bool HasFields { + get { + if (fields != null) + return fields.Count > 0; + + return HasImage && fields_range.Length > 0; + } + } + + public Collection Fields { + get { + if (fields != null) + return fields; + + if (HasImage) + return Module.Read (ref fields, this, (type, reader) => reader.ReadFields (type)); + + return fields = new MemberDefinitionCollection (this); + } + } + + public bool HasEvents { + get { + if (events != null) + return events.Count > 0; + + return HasImage && Module.Read (this, (type, reader) => reader.HasEvents (type)); + } + } + + public Collection Events { + get { + if (events != null) + return events; + + if (HasImage) + return Module.Read (ref events, this, (type, reader) => reader.ReadEvents (type)); + + return events = new MemberDefinitionCollection (this); + } + } + + public bool HasProperties { + get { + if (properties != null) + return properties.Count > 0; + + return HasImage && Module.Read (this, (type, reader) => reader.HasProperties (type)); + } + } + + public Collection Properties { + get { + if (properties != null) + return properties; + + if (HasImage) + return Module.Read (ref properties, this, (type, reader) => reader.ReadProperties (type)); + + return properties = new MemberDefinitionCollection (this); + } + } + + public bool HasSecurityDeclarations { + get { + if (security_declarations != null) + return security_declarations.Count > 0; + + return this.GetHasSecurityDeclarations (Module); + } + } + + public Collection SecurityDeclarations { + get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return this.GetHasCustomAttributes (Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } + } + + public override bool HasGenericParameters { + get { + if (generic_parameters != null) + return generic_parameters.Count > 0; + + return this.GetHasGenericParameters (Module); + } + } + + public override Collection GenericParameters { + get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); } + } + + #region TypeAttributes + + public bool IsNotPublic { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); } + } + + public bool IsPublic { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); } + } + + public bool IsNestedPublic { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); } + } + + public bool IsNestedPrivate { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); } + } + + public bool IsNestedFamily { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); } + } + + public bool IsNestedAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); } + } + + public bool IsNestedFamilyAndAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); } + } + + public bool IsNestedFamilyOrAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); } + } + + public bool IsAutoLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); } + } + + public bool IsSequentialLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); } + } + + public bool IsExplicitLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); } + } + + public bool IsClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); } + } + + public bool IsInterface { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); } + } + + public bool IsAbstract { + get { return attributes.GetAttributes ((uint) TypeAttributes.Abstract); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Abstract, value); } + } + + public bool IsSealed { + get { return attributes.GetAttributes ((uint) TypeAttributes.Sealed); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Sealed, value); } + } + + public bool IsSpecialName { + get { return attributes.GetAttributes ((uint) TypeAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.SpecialName, value); } + } + + public bool IsImport { + get { return attributes.GetAttributes ((uint) TypeAttributes.Import); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Import, value); } + } + + public bool IsSerializable { + get { return attributes.GetAttributes ((uint) TypeAttributes.Serializable); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Serializable, value); } + } + + public bool IsWindowsRuntime { + get { return attributes.GetAttributes ((uint) TypeAttributes.WindowsRuntime); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.WindowsRuntime, value); } + } + + public bool IsAnsiClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); } + } + + public bool IsUnicodeClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); } + } + + public bool IsAutoClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); } + } + + public bool IsBeforeFieldInit { + get { return attributes.GetAttributes ((uint) TypeAttributes.BeforeFieldInit); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.BeforeFieldInit, value); } + } + + public bool IsRuntimeSpecialName { + get { return attributes.GetAttributes ((uint) TypeAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.RTSpecialName, value); } + } + + public bool HasSecurity { + get { return attributes.GetAttributes ((uint) TypeAttributes.HasSecurity); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.HasSecurity, value); } + } + + #endregion + + public bool IsEnum { + get { return base_type != null && base_type.IsTypeOf ("System", "Enum"); } + } + + public override bool IsValueType { + get { + if (base_type == null) + return false; + + return base_type.IsTypeOf ("System", "Enum") || (base_type.IsTypeOf ("System", "ValueType") && !this.IsTypeOf ("System", "Enum")); + } + } + + public override bool IsPrimitive { + get { + ElementType primitive_etype; + return MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype) && primitive_etype.IsPrimitive (); + } + } + + public override MetadataType MetadataType { + get { + ElementType primitive_etype; + if (MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype)) + return (MetadataType) primitive_etype; + + return base.MetadataType; + } + } + + public override bool IsDefinition { + get { return true; } + } + + public new TypeDefinition DeclaringType { + get { return (TypeDefinition) base.DeclaringType; } + set { base.DeclaringType = value; } + } + + internal new TypeDefinitionProjection WindowsRuntimeProjection { + get { return (TypeDefinitionProjection) projection; } + set { projection = value; } + } + + public TypeDefinition (string @namespace, string name, TypeAttributes attributes) + : base (@namespace, name) + { + this.attributes = (uint) attributes; + this.token = new MetadataToken (TokenType.TypeDef); + } + + public TypeDefinition (string @namespace, string name, TypeAttributes attributes, TypeReference baseType) : + this (@namespace, name, attributes) + { + this.BaseType = baseType; + } + + protected override void ClearFullName () + { + base.ClearFullName (); + + if (!HasNestedTypes) + return; + + var nested_types = this.NestedTypes; + + for (int i = 0; i < nested_types.Count; i++) + nested_types [i].ClearFullName (); + } + + public override TypeDefinition Resolve () + { + return this; + } + } + + public sealed class InterfaceImplementation : ICustomAttributeProvider + { + internal TypeDefinition type; + internal MetadataToken token; + + TypeReference interface_type; + Collection custom_attributes; + + public TypeReference InterfaceType { + get { return interface_type; } + set { interface_type = value; } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + if (type == null) + return false; + + return this.GetHasCustomAttributes (type.Module); + } + } + + public Collection CustomAttributes { + get { + if (type == null) + return custom_attributes = new Collection (); + + return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, type.Module)); + } + } + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + internal InterfaceImplementation (TypeReference interfaceType, MetadataToken token) + { + this.interface_type = interfaceType; + this.token = token; + } + + public InterfaceImplementation (TypeReference interfaceType) + { + Mixin.CheckType (interfaceType, Mixin.Argument.interfaceType); + + this.interface_type = interfaceType; + this.token = new MetadataToken (TokenType.InterfaceImpl); + } + } + + class InterfaceImplementationCollection : Collection + { + readonly TypeDefinition type; + + internal InterfaceImplementationCollection (TypeDefinition type) + { + this.type = type; + } + + internal InterfaceImplementationCollection (TypeDefinition type, int length) + : base (length) + { + this.type = type; + } + + protected override void OnAdd (InterfaceImplementation item, int index) + { + item.type = type; + } + + protected override void OnInsert (InterfaceImplementation item, int index) + { + item.type = type; + } + + protected override void OnSet (InterfaceImplementation item, int index) + { + item.type = type; + } + + protected override void OnRemove (InterfaceImplementation item, int index) + { + item.type = null; + } + } + + static partial class Mixin { + + public static TypeReference GetEnumUnderlyingType (this TypeDefinition self) + { + var fields = self.Fields; + + for (int i = 0; i < fields.Count; i++) { + var field = fields [i]; + if (!field.IsStatic) + return field.FieldType; + } + + throw new ArgumentException (); + } + + public static TypeDefinition GetNestedType (this TypeDefinition self, string fullname) + { + if (!self.HasNestedTypes) + return null; + + var nested_types = self.NestedTypes; + + for (int i = 0; i < nested_types.Count; i++) { + var nested_type = nested_types [i]; + + if (nested_type.TypeFullName () == fullname) + return nested_type; + } + + return null; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinitionCollection.cs b/Mono.Cecil.20/Mono.Cecil/TypeDefinitionCollection.cs similarity index 64% rename from Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinitionCollection.cs rename to Mono.Cecil.20/Mono.Cecil/TypeDefinitionCollection.cs index eae71228..95e39b9a 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinitionCollection.cs +++ b/Mono.Cecil.20/Mono.Cecil/TypeDefinitionCollection.cs @@ -1,29 +1,11 @@ // -// TypeDefinitionCollection.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; diff --git a/Mono.Cecil.20/Mono.Cecil/TypeParser.cs b/Mono.Cecil.20/Mono.Cecil/TypeParser.cs new file mode 100644 index 00000000..02f3036f --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/TypeParser.cs @@ -0,0 +1,528 @@ +// +// 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.Text; + +using Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + class TypeParser { + + class Type { + public const int Ptr = -1; + public const int ByRef = -2; + public const int SzArray = -3; + + public string type_fullname; + public string [] nested_names; + public int arity; + public int [] specs; + public Type [] generic_arguments; + public string assembly; + } + + readonly string fullname; + readonly int length; + + int position; + + TypeParser (string fullname) + { + this.fullname = fullname; + this.length = fullname.Length; + } + + Type ParseType (bool fq_name) + { + var type = new Type (); + type.type_fullname = ParsePart (); + + type.nested_names = ParseNestedNames (); + + if (TryGetArity (type)) + type.generic_arguments = ParseGenericArguments (type.arity); + + type.specs = ParseSpecs (); + + if (fq_name) + type.assembly = ParseAssemblyName (); + + return type; + } + + static bool TryGetArity (Type type) + { + int arity = 0; + + TryAddArity (type.type_fullname, ref arity); + + var nested_names = type.nested_names; + if (!nested_names.IsNullOrEmpty ()) { + for (int i = 0; i < nested_names.Length; i++) + TryAddArity (nested_names [i], ref arity); + } + + type.arity = arity; + return arity > 0; + } + + static bool TryGetArity (string name, out int arity) + { + arity = 0; + var index = name.LastIndexOf ('`'); + if (index == -1) + return false; + + return ParseInt32 (name.Substring (index + 1), out arity); + } + + static bool ParseInt32 (string value, out int result) + { + return int.TryParse (value, out result); + } + + static void TryAddArity (string name, ref int arity) + { + int type_arity; + if (!TryGetArity (name, out type_arity)) + return; + + arity += type_arity; + } + + string ParsePart () + { + var part = new StringBuilder (); + while (position < length && !IsDelimiter (fullname [position])) { + if (fullname [position] == '\\') + position++; + + part.Append (fullname [position++]); + } + + return part.ToString (); + } + + static bool IsDelimiter (char chr) + { + return "+,[]*&".IndexOf (chr) != -1; + } + + void TryParseWhiteSpace () + { + while (position < length && Char.IsWhiteSpace (fullname [position])) + position++; + } + + string [] ParseNestedNames () + { + string [] nested_names = null; + while (TryParse ('+')) + Add (ref nested_names, ParsePart ()); + + return nested_names; + } + + bool TryParse (char chr) + { + if (position < length && fullname [position] == chr) { + position++; + return true; + } + + return false; + } + + static void Add (ref T [] array, T item) + { + array = array.Add (item); + } + + int [] ParseSpecs () + { + int [] specs = null; + + while (position < length) { + switch (fullname [position]) { + case '*': + position++; + Add (ref specs, Type.Ptr); + break; + case '&': + position++; + Add (ref specs, Type.ByRef); + break; + case '[': + position++; + switch (fullname [position]) { + case ']': + position++; + Add (ref specs, Type.SzArray); + break; + case '*': + position++; + Add (ref specs, 1); + break; + default: + var rank = 1; + while (TryParse (',')) + rank++; + + Add (ref specs, rank); + + TryParse (']'); + break; + } + break; + default: + return specs; + } + } + + return specs; + } + + Type [] ParseGenericArguments (int arity) + { + Type [] generic_arguments = null; + + if (position == length || fullname [position] != '[') + return generic_arguments; + + TryParse ('['); + + for (int i = 0; i < arity; i++) { + var fq_argument = TryParse ('['); + Add (ref generic_arguments, ParseType (fq_argument)); + if (fq_argument) + TryParse (']'); + + TryParse (','); + TryParseWhiteSpace (); + } + + TryParse (']'); + + return generic_arguments; + } + + string ParseAssemblyName () + { + if (!TryParse (',')) + return string.Empty; + + TryParseWhiteSpace (); + + var start = position; + while (position < length) { + var chr = fullname [position]; + if (chr == '[' || chr == ']') + break; + + position++; + } + + return fullname.Substring (start, position - start); + } + + public static TypeReference ParseType (ModuleDefinition module, string fullname) + { + if (string.IsNullOrEmpty (fullname)) + return null; + + var parser = new TypeParser (fullname); + return GetTypeReference (module, parser.ParseType (true)); + } + + static TypeReference GetTypeReference (ModuleDefinition module, Type type_info) + { + TypeReference type; + if (!TryGetDefinition (module, type_info, out type)) + type = CreateReference (type_info, module, GetMetadataScope (module, type_info)); + + return CreateSpecs (type, type_info); + } + + static TypeReference CreateSpecs (TypeReference type, Type type_info) + { + type = TryCreateGenericInstanceType (type, type_info); + + var specs = type_info.specs; + if (specs.IsNullOrEmpty ()) + return type; + + for (int i = 0; i < specs.Length; i++) { + switch (specs [i]) { + case Type.Ptr: + type = new PointerType (type); + break; + case Type.ByRef: + type = new ByReferenceType (type); + break; + case Type.SzArray: + type = new ArrayType (type); + break; + default: + var array = new ArrayType (type); + array.Dimensions.Clear (); + + for (int j = 0; j < specs [i]; j++) + array.Dimensions.Add (new ArrayDimension ()); + + type = array; + break; + } + } + + return type; + } + + static TypeReference TryCreateGenericInstanceType (TypeReference type, Type type_info) + { + var generic_arguments = type_info.generic_arguments; + if (generic_arguments.IsNullOrEmpty ()) + return type; + + var instance = new GenericInstanceType (type); + var instance_arguments = instance.GenericArguments; + + for (int i = 0; i < generic_arguments.Length; i++) + instance_arguments.Add (GetTypeReference (type.Module, generic_arguments [i])); + + return instance; + } + + public static void SplitFullName (string fullname, out string @namespace, out string name) + { + var last_dot = fullname.LastIndexOf ('.'); + + if (last_dot == -1) { + @namespace = string.Empty; + name = fullname; + } else { + @namespace = fullname.Substring (0, last_dot); + name = fullname.Substring (last_dot + 1); + } + } + + static TypeReference CreateReference (Type type_info, ModuleDefinition module, IMetadataScope scope) + { + string @namespace, name; + SplitFullName (type_info.type_fullname, out @namespace, out name); + + var type = new TypeReference (@namespace, name, module, scope); + MetadataSystem.TryProcessPrimitiveTypeReference (type); + + AdjustGenericParameters (type); + + var nested_names = type_info.nested_names; + if (nested_names.IsNullOrEmpty ()) + return type; + + for (int i = 0; i < nested_names.Length; i++) { + type = new TypeReference (string.Empty, nested_names [i], module, null) { + DeclaringType = type, + }; + + AdjustGenericParameters (type); + } + + return type; + } + + static void AdjustGenericParameters (TypeReference type) + { + int arity; + if (!TryGetArity (type.Name, out arity)) + return; + + for (int i = 0; i < arity; i++) + type.GenericParameters.Add (new GenericParameter (type)); + } + + static IMetadataScope GetMetadataScope (ModuleDefinition module, Type type_info) + { + if (string.IsNullOrEmpty (type_info.assembly)) + return module.TypeSystem.CoreLibrary; + + AssemblyNameReference match; + var reference = AssemblyNameReference.Parse (type_info.assembly); + + return module.TryGetAssemblyNameReference (reference, out match) + ? match + : reference; + } + + static bool TryGetDefinition (ModuleDefinition module, Type type_info, out TypeReference type) + { + type = null; + if (!TryCurrentModule (module, type_info)) + return false; + + var typedef = module.GetType (type_info.type_fullname); + if (typedef == null) + return false; + + var nested_names = type_info.nested_names; + if (!nested_names.IsNullOrEmpty ()) { + for (int i = 0; i < nested_names.Length; i++) { + var nested_type = typedef.GetNestedType (nested_names [i]); + if (nested_type == null) + return false; + + typedef = nested_type; + } + } + + type = typedef; + return true; + } + + static bool TryCurrentModule (ModuleDefinition module, Type type_info) + { + if (string.IsNullOrEmpty (type_info.assembly)) + return true; + + if (module.assembly != null && module.assembly.Name.FullName == type_info.assembly) + return true; + + return false; + } + + public static string ToParseable (TypeReference type) + { + if (type == null) + return null; + + var name = new StringBuilder (); + AppendType (type, name, true, true); + return name.ToString (); + } + + static void AppendNamePart (string part, StringBuilder name) + { + foreach (var c in part) { + if (IsDelimiter (c)) + name.Append ('\\'); + + name.Append (c); + } + } + + static void AppendType (TypeReference type, StringBuilder name, bool fq_name, bool top_level) + { + var element_type = type.GetElementType (); + + var declaring_type = element_type.DeclaringType; + if (declaring_type != null) { + AppendType (declaring_type, name, false, top_level); + name.Append ('+'); + } + + var @namespace = type.Namespace; + if (!string.IsNullOrEmpty (@namespace)) { + AppendNamePart (@namespace, name); + name.Append ('.'); + } + + AppendNamePart (element_type.Name, name); + + if (!fq_name) + return; + + if (type.IsTypeSpecification ()) + AppendTypeSpecification ((TypeSpecification) type, name); + + if (RequiresFullyQualifiedName (type, top_level)) { + name.Append (", "); + name.Append (GetScopeFullName (type)); + } + } + + static string GetScopeFullName (TypeReference type) + { + var scope = type.Scope; + switch (scope.MetadataScopeType) { + case MetadataScopeType.AssemblyNameReference: + return ((AssemblyNameReference) scope).FullName; + case MetadataScopeType.ModuleDefinition: + return ((ModuleDefinition) scope).Assembly.Name.FullName; + } + + throw new ArgumentException (); + } + + static void AppendTypeSpecification (TypeSpecification type, StringBuilder name) + { + if (type.ElementType.IsTypeSpecification ()) + AppendTypeSpecification ((TypeSpecification) type.ElementType, name); + + switch (type.etype) { + case ElementType.Ptr: + name.Append ('*'); + break; + case ElementType.ByRef: + name.Append ('&'); + break; + case ElementType.SzArray: + case ElementType.Array: + var array = (ArrayType) type; + if (array.IsVector) { + name.Append ("[]"); + } else { + name.Append ('['); + for (int i = 1; i < array.Rank; i++) + name.Append (','); + name.Append (']'); + } + break; + case ElementType.GenericInst: + var instance = (GenericInstanceType) type; + var arguments = instance.GenericArguments; + + name.Append ('['); + + for (int i = 0; i < arguments.Count; i++) { + if (i > 0) + name.Append (','); + + var argument = arguments [i]; + var requires_fqname = argument.Scope != argument.Module; + + if (requires_fqname) + name.Append ('['); + + AppendType (argument, name, true, false); + + if (requires_fqname) + name.Append (']'); + } + + name.Append (']'); + break; + default: + return; + } + } + + static bool RequiresFullyQualifiedName (TypeReference type, bool top_level) + { + if (type.Scope == type.Module) + return false; + + if (type.Scope.Name == "mscorlib" && top_level) + return false; + + return true; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/TypeReference.cs b/Mono.Cecil.20/Mono.Cecil/TypeReference.cs new file mode 100644 index 00000000..e5b10d60 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/TypeReference.cs @@ -0,0 +1,361 @@ +// +// 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 Mono.Cecil.Metadata; +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public enum MetadataType : byte { + Void = ElementType.Void, + Boolean = ElementType.Boolean, + Char = ElementType.Char, + SByte = ElementType.I1, + Byte = ElementType.U1, + Int16 = ElementType.I2, + UInt16 = ElementType.U2, + Int32 = ElementType.I4, + UInt32 = ElementType.U4, + Int64 = ElementType.I8, + UInt64 = ElementType.U8, + Single = ElementType.R4, + Double = ElementType.R8, + String = ElementType.String, + Pointer = ElementType.Ptr, + ByReference = ElementType.ByRef, + ValueType = ElementType.ValueType, + Class = ElementType.Class, + Var = ElementType.Var, + Array = ElementType.Array, + GenericInstance = ElementType.GenericInst, + TypedByReference = ElementType.TypedByRef, + IntPtr = ElementType.I, + UIntPtr = ElementType.U, + FunctionPointer = ElementType.FnPtr, + Object = ElementType.Object, + MVar = ElementType.MVar, + RequiredModifier = ElementType.CModReqD, + OptionalModifier = ElementType.CModOpt, + Sentinel = ElementType.Sentinel, + Pinned = ElementType.Pinned, + } + + public class TypeReference : MemberReference, IGenericParameterProvider, IGenericContext { + + string @namespace; + int hashCode = -1; + static int instance_id; + bool value_type; + internal IMetadataScope scope; + internal ModuleDefinition module; + + internal ElementType etype = ElementType.None; + + string fullname; + + protected Collection generic_parameters; + + public override string Name { + get { return base.Name; } + set { + if (IsWindowsRuntimeProjection && value != base.Name) + throw new InvalidOperationException ("Projected type reference name can't be changed."); + base.Name = value; + ClearFullName (); + } + } + + public virtual string Namespace { + get { return @namespace; } + set { + if (IsWindowsRuntimeProjection && value != @namespace) + throw new InvalidOperationException ("Projected type reference namespace can't be changed."); + @namespace = value; + ClearFullName (); + } + } + + public virtual bool IsValueType { + get { return value_type; } + set { value_type = value; } + } + + public override ModuleDefinition Module { + get { + if (module != null) + return module; + + var declaring_type = this.DeclaringType; + if (declaring_type != null) + return declaring_type.Module; + + return null; + } + } + + internal new TypeReferenceProjection WindowsRuntimeProjection { + get { return (TypeReferenceProjection) projection; } + set { projection = value; } + } + + IGenericParameterProvider IGenericContext.Type { + get { return this; } + } + + IGenericParameterProvider IGenericContext.Method { + get { return null; } + } + + GenericParameterType IGenericParameterProvider.GenericParameterType { + get { return GenericParameterType.Type; } + } + + public virtual bool HasGenericParameters { + get { return !generic_parameters.IsNullOrEmpty (); } + } + + public virtual Collection GenericParameters { + get { + if (generic_parameters != null) + return generic_parameters; + + return generic_parameters = new GenericParameterCollection (this); + } + } + + public virtual IMetadataScope Scope { + get { + var declaring_type = this.DeclaringType; + if (declaring_type != null) + return declaring_type.Scope; + + return scope; + } + set { + var declaring_type = this.DeclaringType; + if (declaring_type != null) { + if (IsWindowsRuntimeProjection && value != declaring_type.Scope) + throw new InvalidOperationException ("Projected type scope can't be changed."); + declaring_type.Scope = value; + return; + } + + if (IsWindowsRuntimeProjection && value != scope) + throw new InvalidOperationException ("Projected type scope can't be changed."); + scope = value; + } + } + + public bool IsNested { + get { return this.DeclaringType != null; } + } + + public override TypeReference DeclaringType { + get { return base.DeclaringType; } + set { + if (IsWindowsRuntimeProjection && value != base.DeclaringType) + throw new InvalidOperationException ("Projected type declaring type can't be changed."); + base.DeclaringType = value; + ClearFullName (); + } + } + + public override string FullName { + get { + if (fullname != null) + return fullname; + + fullname = this.TypeFullName (); + + if (IsNested) + fullname = DeclaringType.FullName + "/" + fullname; + + return fullname; + } + } + + public virtual bool IsByReference { + get { return false; } + } + + public virtual bool IsPointer { + get { return false; } + } + + public virtual bool IsSentinel { + get { return false; } + } + + public virtual bool IsArray { + get { return false; } + } + + public virtual bool IsGenericParameter { + get { return false; } + } + + public virtual bool IsGenericInstance { + get { return false; } + } + + public virtual bool IsRequiredModifier { + get { return false; } + } + + public virtual bool IsOptionalModifier { + get { return false; } + } + + public virtual bool IsPinned { + get { return false; } + } + + public virtual bool IsFunctionPointer { + get { return false; } + } + + public override int GetHashCode() + { + if (hashCode == -1) + hashCode = System.Threading.Interlocked.Add(ref instance_id, 1); + return hashCode; + } + + public virtual bool IsPrimitive { + get { return etype.IsPrimitive (); } + } + + public virtual MetadataType MetadataType { + get { + switch (etype) { + case ElementType.None: + return IsValueType ? MetadataType.ValueType : MetadataType.Class; + default: + return (MetadataType) etype; + } + } + } + + protected TypeReference (string @namespace, string name) + : base (name) + { + this.@namespace = @namespace ?? string.Empty; + this.token = new MetadataToken (TokenType.TypeRef, 0); + } + + public TypeReference (string @namespace, string name, ModuleDefinition module, IMetadataScope scope) + : this (@namespace, name) + { + this.module = module; + this.scope = scope; + } + + public TypeReference (string @namespace, string name, ModuleDefinition module, IMetadataScope scope, bool valueType) : + this (@namespace, name, module, scope) + { + value_type = valueType; + } + + protected virtual void ClearFullName () + { + this.fullname = null; + } + + public virtual TypeReference GetElementType () + { + return this; + } + + protected override IMemberDefinition ResolveDefinition () + { + return this.Resolve (); + } + + public new virtual TypeDefinition Resolve () + { + var module = this.Module; + if (module == null) + throw new NotSupportedException (); + + return module.Resolve (this); + } + } + + static partial class Mixin { + + public static bool IsPrimitive (this ElementType self) + { + switch (self) { + case ElementType.Boolean: + case ElementType.Char: + case ElementType.I: + case ElementType.U: + case ElementType.I1: + case ElementType.U1: + case ElementType.I2: + case ElementType.U2: + case ElementType.I4: + case ElementType.U4: + case ElementType.I8: + case ElementType.U8: + case ElementType.R4: + case ElementType.R8: + return true; + default: + return false; + } + } + + public static string TypeFullName (this TypeReference self) + { + return string.IsNullOrEmpty (self.Namespace) + ? self.Name + : self.Namespace + '.' + self.Name; + } + + public static bool IsTypeOf (this TypeReference self, string @namespace, string name) + { + return self.Name == name + && self.Namespace == @namespace; + } + + public static bool IsTypeSpecification (this TypeReference type) + { + switch (type.etype) { + case ElementType.Array: + case ElementType.ByRef: + case ElementType.CModOpt: + case ElementType.CModReqD: + case ElementType.FnPtr: + case ElementType.GenericInst: + case ElementType.MVar: + case ElementType.Pinned: + case ElementType.Ptr: + case ElementType.SzArray: + case ElementType.Sentinel: + case ElementType.Var: + return true; + } + + return false; + } + + public static TypeDefinition CheckedResolve (this TypeReference self) + { + var type = self.Resolve (); + if (type == null) + throw new ResolutionException (self); + + return type; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/TypeSpecification.cs b/Mono.Cecil.20/Mono.Cecil/TypeSpecification.cs new file mode 100644 index 00000000..06d6a8a7 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/TypeSpecification.cs @@ -0,0 +1,68 @@ +// +// 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 Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public abstract class TypeSpecification : TypeReference { + + readonly TypeReference element_type; + + public TypeReference ElementType { + get { return element_type; } + } + + public override string Name { + get { return element_type.Name; } + set { throw new InvalidOperationException (); } + } + + public override string Namespace { + get { return element_type.Namespace; } + set { throw new InvalidOperationException (); } + } + + public override IMetadataScope Scope { + get { return element_type.Scope; } + set { throw new InvalidOperationException (); } + } + + public override ModuleDefinition Module { + get { return element_type.Module; } + } + + public override string FullName { + get { return element_type.FullName; } + } + + public override bool ContainsGenericParameter { + get { return element_type.ContainsGenericParameter; } + } + + public override MetadataType MetadataType { + get { return (MetadataType) etype; } + } + + internal TypeSpecification (TypeReference type) + : base (null, null) + { + this.element_type = type; + this.token = new MetadataToken (TokenType.TypeSpec); + } + + public override TypeReference GetElementType () + { + return element_type; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/TypeSystem.cs b/Mono.Cecil.20/Mono.Cecil/TypeSystem.cs new file mode 100644 index 00000000..3b5202c1 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/TypeSystem.cs @@ -0,0 +1,325 @@ +// +// 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 Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public abstract class TypeSystem { + + sealed class CoreTypeSystem : TypeSystem { + + public CoreTypeSystem (ModuleDefinition module) + : base (module) + { + } + + internal override TypeReference LookupType (string @namespace, string name) + { + var type = LookupTypeDefinition (@namespace, name) ?? LookupTypeForwarded (@namespace, name); + if (type != null) + return type; + + throw new NotSupportedException (); + } + + TypeReference LookupTypeDefinition (string @namespace, string name) + { + var metadata = module.MetadataSystem; + if (metadata.Types == null) + Initialize (module.Types); + + return module.Read (new Row (@namespace, name), (row, reader) => { + var types = reader.metadata.Types; + + for (int i = 0; i < types.Length; i++) { + if (types [i] == null) + types [i] = reader.GetTypeDefinition ((uint) i + 1); + + var type = types [i]; + + if (type.Name == row.Col2 && type.Namespace == row.Col1) + return type; + } + + return null; + }); + } + + TypeReference LookupTypeForwarded (string @namespace, string name) + { + if (!module.HasExportedTypes) + return null; + + var exported_types = module.ExportedTypes; + for (int i = 0; i < exported_types.Count; i++) { + var exported_type = exported_types [i]; + + if (exported_type.Name == name && exported_type.Namespace == @namespace) + return exported_type.CreateReference (); + } + + return null; + } + + static void Initialize (object obj) + { + } + } + + sealed class CommonTypeSystem : TypeSystem { + + AssemblyNameReference core_library; + + public CommonTypeSystem (ModuleDefinition module) + : base (module) + { + } + + internal override TypeReference LookupType (string @namespace, string name) + { + return CreateTypeReference (@namespace, name); + } + + public AssemblyNameReference GetCoreLibraryReference () + { + if (core_library != null) + return core_library; + + if (module.TryGetCoreLibraryReference (out core_library)) + return core_library; + + core_library = new AssemblyNameReference { + Name = Mixin.mscorlib, + Version = GetCorlibVersion (), + PublicKeyToken = new byte [] { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 }, + }; + + module.AssemblyReferences.Add (core_library); + + return core_library; + } + + Version GetCorlibVersion () + { + switch (module.Runtime) { + case TargetRuntime.Net_1_0: + case TargetRuntime.Net_1_1: + return new Version (1, 0, 0, 0); + case TargetRuntime.Net_2_0: + return new Version (2, 0, 0, 0); + case TargetRuntime.Net_4_0: + return new Version (4, 0, 0, 0); + default: + throw new NotSupportedException (); + } + } + + TypeReference CreateTypeReference (string @namespace, string name) + { + return new TypeReference (@namespace, name, module, GetCoreLibraryReference ()); + } + } + + readonly ModuleDefinition module; + + TypeReference type_object; + TypeReference type_void; + TypeReference type_bool; + TypeReference type_char; + TypeReference type_sbyte; + TypeReference type_byte; + TypeReference type_int16; + TypeReference type_uint16; + TypeReference type_int32; + TypeReference type_uint32; + TypeReference type_int64; + TypeReference type_uint64; + TypeReference type_single; + TypeReference type_double; + TypeReference type_intptr; + TypeReference type_uintptr; + TypeReference type_string; + TypeReference type_typedref; + + TypeSystem (ModuleDefinition module) + { + this.module = module; + } + + internal static TypeSystem CreateTypeSystem (ModuleDefinition module) + { + if (module.IsCoreLibrary ()) + return new CoreTypeSystem (module); + + return new CommonTypeSystem (module); + } + + internal abstract TypeReference LookupType (string @namespace, string name); + + TypeReference LookupSystemType (ref TypeReference reference, string name, ElementType element_type) + { + lock (module.SyncRoot) { + if (reference != null) + return reference; + var type = LookupType ("System", name); + type.etype = element_type; + return reference = type; + } + } + + TypeReference LookupSystemValueType (ref TypeReference typeRef, string name, ElementType element_type) + { + lock (module.SyncRoot) { + if (typeRef != null) + return typeRef; + var type = LookupType ("System", name); + type.etype = element_type; + type.IsValueType = true; + return typeRef = type; + } + } + + [Obsolete ("Use CoreLibrary")] + public IMetadataScope Corlib { + get { return CoreLibrary; } + } + + public IMetadataScope CoreLibrary { + get { + var common = this as CommonTypeSystem; + if (common == null) + return module; + + return common.GetCoreLibraryReference (); + } + } + + public TypeReference Object { + get { return type_object ?? (LookupSystemType (ref type_object, "Object", ElementType.Object)); } + } + + public TypeReference Void { + get { return type_void ?? (LookupSystemType (ref type_void, "Void", ElementType.Void)); } + } + + public TypeReference Boolean { + get { return type_bool ?? (LookupSystemValueType (ref type_bool, "Boolean", ElementType.Boolean)); } + } + + public TypeReference Char { + get { return type_char ?? (LookupSystemValueType (ref type_char, "Char", ElementType.Char)); } + } + + public TypeReference SByte { + get { return type_sbyte ?? (LookupSystemValueType (ref type_sbyte, "SByte", ElementType.I1)); } + } + + public TypeReference Byte { + get { return type_byte ?? (LookupSystemValueType (ref type_byte, "Byte", ElementType.U1)); } + } + + public TypeReference Int16 { + get { return type_int16 ?? (LookupSystemValueType (ref type_int16, "Int16", ElementType.I2)); } + } + + public TypeReference UInt16 { + get { return type_uint16 ?? (LookupSystemValueType (ref type_uint16, "UInt16", ElementType.U2)); } + } + + public TypeReference Int32 { + get { return type_int32 ?? (LookupSystemValueType (ref type_int32, "Int32", ElementType.I4)); } + } + + public TypeReference UInt32 { + get { return type_uint32 ?? (LookupSystemValueType (ref type_uint32, "UInt32", ElementType.U4)); } + } + + public TypeReference Int64 { + get { return type_int64 ?? (LookupSystemValueType (ref type_int64, "Int64", ElementType.I8)); } + } + + public TypeReference UInt64 { + get { return type_uint64 ?? (LookupSystemValueType (ref type_uint64, "UInt64", ElementType.U8)); } + } + + public TypeReference Single { + get { return type_single ?? (LookupSystemValueType (ref type_single, "Single", ElementType.R4)); } + } + + public TypeReference Double { + get { return type_double ?? (LookupSystemValueType (ref type_double, "Double", ElementType.R8)); } + } + + public TypeReference IntPtr { + get { return type_intptr ?? (LookupSystemValueType (ref type_intptr, "IntPtr", ElementType.I)); } + } + + public TypeReference UIntPtr { + get { return type_uintptr ?? (LookupSystemValueType (ref type_uintptr, "UIntPtr", ElementType.U)); } + } + + public TypeReference String { + get { return type_string ?? (LookupSystemType (ref type_string, "String", ElementType.String)); } + } + + public TypeReference TypedReference { + get { return type_typedref ?? (LookupSystemValueType (ref type_typedref, "TypedReference", ElementType.TypedByRef)); } + } + } + + static partial class Mixin { + + public const string mscorlib = "mscorlib"; + public const string system_runtime = "System.Runtime"; + public const string system_private_corelib = "System.Private.CoreLib"; + public const string netstandard = "netstandard"; + + public static bool TryGetCoreLibraryReference (this ModuleDefinition module, out AssemblyNameReference reference) + { + var references = module.AssemblyReferences; + + for (int i = 0; i < references.Count; i++) { + reference = references [i]; + if (IsCoreLibrary (reference)) + return true; + } + + reference = null; + return false; + + } + + public static bool IsCoreLibrary (this ModuleDefinition module) + { + if (module.Assembly == null) + return false; + + if (!IsCoreLibrary (module.Assembly.Name)) + return false; + + if (module.HasImage && module.Read (module, (m, reader) => reader.image.GetTableLength (Table.AssemblyRef) > 0)) + return false; + + return true; + } + + static bool IsCoreLibrary (AssemblyNameReference reference) + { + var name = reference.Name; + return name == mscorlib + || name == system_runtime + || name == system_private_corelib + || name == netstandard; + } + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/VariantType.cs b/Mono.Cecil.20/Mono.Cecil/VariantType.cs new file mode 100644 index 00000000..81aa7fa4 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/VariantType.cs @@ -0,0 +1,35 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum VariantType { + None = 0, + I2 = 2, + I4 = 3, + R4 = 4, + R8 = 5, + CY = 6, + Date = 7, + BStr = 8, + Dispatch = 9, + Error = 10, + Bool = 11, + Variant = 12, + Unknown = 13, + Decimal = 14, + I1 = 16, + UI1 = 17, + UI2 = 18, + UI4 = 19, + Int = 22, + UInt = 23 + } +} diff --git a/Mono.Cecil.20/Mono.Cecil/WindowsRuntimeProjections.cs b/Mono.Cecil.20/Mono.Cecil/WindowsRuntimeProjections.cs new file mode 100644 index 00000000..04ba8c60 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil/WindowsRuntimeProjections.cs @@ -0,0 +1,875 @@ +// +// 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.Threading; +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + sealed class MemberReferenceProjection { + + public readonly string Name; + public readonly MemberReferenceTreatment Treatment; + + public MemberReferenceProjection (MemberReference member, MemberReferenceTreatment treatment) + { + Name = member.Name; + Treatment = treatment; + } + } + + sealed class TypeDefinitionProjection { + + public readonly TypeAttributes Attributes; + public readonly string Name; + public readonly TypeDefinitionTreatment Treatment; + + public TypeDefinitionProjection (TypeDefinition type, TypeDefinitionTreatment treatment) + { + Attributes = type.Attributes; + Name = type.Name; + Treatment = treatment; + } + } + + sealed class TypeReferenceProjection { + + public readonly string Name; + public readonly string Namespace; + public readonly IMetadataScope Scope; + public readonly TypeReferenceTreatment Treatment; + + public TypeReferenceProjection (TypeReference type, TypeReferenceTreatment treatment) + { + Name = type.Name; + Namespace = type.Namespace; + Scope = type.Scope; + Treatment = treatment; + } + } + + sealed class MethodDefinitionProjection { + + public readonly MethodAttributes Attributes; + public readonly MethodImplAttributes ImplAttributes; + public readonly string Name; + public readonly MethodDefinitionTreatment Treatment; + + public MethodDefinitionProjection (MethodDefinition method, MethodDefinitionTreatment treatment) + { + Attributes = method.Attributes; + ImplAttributes = method.ImplAttributes; + Name = method.Name; + Treatment = treatment; + } + } + + sealed class FieldDefinitionProjection { + + public readonly FieldAttributes Attributes; + public readonly FieldDefinitionTreatment Treatment; + + public FieldDefinitionProjection (FieldDefinition field, FieldDefinitionTreatment treatment) + { + Attributes = field.Attributes; + Treatment = treatment; + } + } + + sealed class CustomAttributeValueProjection { + + public readonly AttributeTargets Targets; + public readonly CustomAttributeValueTreatment Treatment; + + public CustomAttributeValueProjection (AttributeTargets targets, CustomAttributeValueTreatment treatment) + { + Targets = targets; + Treatment = treatment; + } + } + + sealed class WindowsRuntimeProjections { + + struct ProjectionInfo { + + public readonly string WinRTNamespace; + public readonly string ClrNamespace; + public readonly string ClrName; + public readonly string ClrAssembly; + public readonly bool Attribute; + public readonly bool Disposable; + + public ProjectionInfo (string winrt_namespace, string clr_namespace, string clr_name, string clr_assembly, bool attribute = false, bool disposable = false) + { + WinRTNamespace = winrt_namespace; + ClrNamespace = clr_namespace; + ClrName = clr_name; + ClrAssembly = clr_assembly; + Attribute = attribute; + Disposable = disposable; + } + } + + static readonly Version version = new Version (4, 0, 0, 0); + + static readonly byte[] contract_pk_token = { + 0xB0, 0x3F, 0x5F, 0x7F, 0x11, 0xD5, 0x0A, 0x3A + }; + + static readonly byte[] contract_pk = { + 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x07, 0xD1, 0xFA, 0x57, 0xC4, 0xAE, 0xD9, 0xF0, 0xA3, 0x2E, 0x84, 0xAA, 0x0F, 0xAE, 0xFD, 0x0D, + 0xE9, 0xE8, 0xFD, 0x6A, 0xEC, 0x8F, 0x87, 0xFB, 0x03, 0x76, 0x6C, 0x83, 0x4C, 0x99, 0x92, 0x1E, + 0xB2, 0x3B, 0xE7, 0x9A, 0xD9, 0xD5, 0xDC, 0xC1, 0xDD, 0x9A, 0xD2, 0x36, 0x13, 0x21, 0x02, 0x90, + 0x0B, 0x72, 0x3C, 0xF9, 0x80, 0x95, 0x7F, 0xC4, 0xE1, 0x77, 0x10, 0x8F, 0xC6, 0x07, 0x77, 0x4F, + 0x29, 0xE8, 0x32, 0x0E, 0x92, 0xEA, 0x05, 0xEC, 0xE4, 0xE8, 0x21, 0xC0, 0xA5, 0xEF, 0xE8, 0xF1, + 0x64, 0x5C, 0x4C, 0x0C, 0x93, 0xC1, 0xAB, 0x99, 0x28, 0x5D, 0x62, 0x2C, 0xAA, 0x65, 0x2C, 0x1D, + 0xFA, 0xD6, 0x3D, 0x74, 0x5D, 0x6F, 0x2D, 0xE5, 0xF1, 0x7E, 0x5E, 0xAF, 0x0F, 0xC4, 0x96, 0x3D, + 0x26, 0x1C, 0x8A, 0x12, 0x43, 0x65, 0x18, 0x20, 0x6D, 0xC0, 0x93, 0x34, 0x4D, 0x5A, 0xD2, 0x93 + }; + + static Dictionary projections; + + static Dictionary Projections + { + get { + if (projections != null) + return projections; + + return projections = new Dictionary { + { "AttributeTargets", new ProjectionInfo ("Windows.Foundation.Metadata", "System", "AttributeTargets", "System.Runtime") }, + { "AttributeUsageAttribute", new ProjectionInfo ("Windows.Foundation.Metadata", "System", "AttributeUsageAttribute", "System.Runtime", attribute: true) }, + { "Color", new ProjectionInfo ("Windows.UI", "Windows.UI", "Color", "System.Runtime.WindowsRuntime") }, + { "CornerRadius", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "CornerRadius", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "DateTime", new ProjectionInfo ("Windows.Foundation", "System", "DateTimeOffset", "System.Runtime") }, + { "Duration", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "Duration", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "DurationType", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "DurationType", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "EventHandler`1", new ProjectionInfo ("Windows.Foundation", "System", "EventHandler`1", "System.Runtime") }, + { "EventRegistrationToken", new ProjectionInfo ("Windows.Foundation", "System.Runtime.InteropServices.WindowsRuntime", "EventRegistrationToken", "System.Runtime.InteropServices.WindowsRuntime") }, + { "GeneratorPosition", new ProjectionInfo ("Windows.UI.Xaml.Controls.Primitives", "Windows.UI.Xaml.Controls.Primitives", "GeneratorPosition", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "GridLength", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "GridLength", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "GridUnitType", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "GridUnitType", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "HResult", new ProjectionInfo ("Windows.Foundation", "System", "Exception", "System.Runtime") }, + { "IBindableIterable", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections", "IEnumerable", "System.Runtime") }, + { "IBindableVector", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections", "IList", "System.Runtime") }, + { "IClosable", new ProjectionInfo ("Windows.Foundation", "System", "IDisposable", "System.Runtime", disposable: true) }, + { "ICommand", new ProjectionInfo ("Windows.UI.Xaml.Input", "System.Windows.Input", "ICommand", "System.ObjectModel") }, + { "IIterable`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IEnumerable`1", "System.Runtime") }, + { "IKeyValuePair`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "KeyValuePair`2", "System.Runtime") }, + { "IMapView`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IReadOnlyDictionary`2", "System.Runtime") }, + { "IMap`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IDictionary`2", "System.Runtime") }, + { "INotifyCollectionChanged", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "INotifyCollectionChanged", "System.ObjectModel") }, + { "INotifyPropertyChanged", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "INotifyPropertyChanged", "System.ObjectModel") }, + { "IReference`1", new ProjectionInfo ("Windows.Foundation", "System", "Nullable`1", "System.Runtime") }, + { "IVectorView`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IReadOnlyList`1", "System.Runtime") }, + { "IVector`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IList`1", "System.Runtime") }, + { "KeyTime", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "KeyTime", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "Matrix", new ProjectionInfo ("Windows.UI.Xaml.Media", "Windows.UI.Xaml.Media", "Matrix", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "Matrix3D", new ProjectionInfo ("Windows.UI.Xaml.Media.Media3D", "Windows.UI.Xaml.Media.Media3D", "Matrix3D", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "Matrix3x2", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Matrix3x2", "System.Numerics.Vectors") }, + { "Matrix4x4", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Matrix4x4", "System.Numerics.Vectors") }, + { "NotifyCollectionChangedAction", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedAction", "System.ObjectModel") }, + { "NotifyCollectionChangedEventArgs", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedEventArgs", "System.ObjectModel") }, + { "NotifyCollectionChangedEventHandler", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedEventHandler", "System.ObjectModel") }, + { "Plane", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Plane", "System.Numerics.Vectors") }, + { "Point", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Point", "System.Runtime.WindowsRuntime") }, + { "PropertyChangedEventArgs", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "PropertyChangedEventArgs", "System.ObjectModel") }, + { "PropertyChangedEventHandler", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "PropertyChangedEventHandler", "System.ObjectModel") }, + { "Quaternion", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Quaternion", "System.Numerics.Vectors") }, + { "Rect", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Rect", "System.Runtime.WindowsRuntime") }, + { "RepeatBehavior", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "RepeatBehavior", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "RepeatBehaviorType", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "RepeatBehaviorType", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "Size", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Size", "System.Runtime.WindowsRuntime") }, + { "Thickness", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "Thickness", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "TimeSpan", new ProjectionInfo ("Windows.Foundation", "System", "TimeSpan", "System.Runtime") }, + { "TypeName", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System", "Type", "System.Runtime") }, + { "Uri", new ProjectionInfo ("Windows.Foundation", "System", "Uri", "System.Runtime") }, + { "Vector2", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector2", "System.Numerics.Vectors") }, + { "Vector3", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector3", "System.Numerics.Vectors") }, + { "Vector4", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector4", "System.Numerics.Vectors") }, + }; + } + } + + readonly ModuleDefinition module; + Version corlib_version = new Version (255, 255, 255, 255); + AssemblyNameReference[] virtual_references; + + AssemblyNameReference[] VirtualReferences { + get { + if (virtual_references == null) { + // force module to read its assembly references. that will in turn initialize virtual_references + Mixin.Read (module.AssemblyReferences); + } + + return virtual_references; + } + } + + public WindowsRuntimeProjections (ModuleDefinition module) + { + this.module = module; + } + + public static void Project (TypeDefinition type) + { + var treatment = TypeDefinitionTreatment.None; + var metadata_kind = type.Module.MetadataKind; + + if (type.IsWindowsRuntime) { + if (metadata_kind == MetadataKind.WindowsMetadata) { + treatment = GetWellKnownTypeDefinitionTreatment (type); + if (treatment != TypeDefinitionTreatment.None) { + ApplyProjection (type, new TypeDefinitionProjection (type, treatment)); + return; + } + + var base_type = type.BaseType; + if (base_type != null && IsAttribute (base_type)) + treatment = TypeDefinitionTreatment.NormalAttribute; + else + treatment = TypeDefinitionTreatment.NormalType; + } + else if (metadata_kind == MetadataKind.ManagedWindowsMetadata && NeedsWindowsRuntimePrefix (type)) + treatment = TypeDefinitionTreatment.PrefixWindowsRuntimeName; + + if (treatment == TypeDefinitionTreatment.PrefixWindowsRuntimeName || treatment == TypeDefinitionTreatment.NormalType) + if (!type.IsInterface && HasAttribute (type, "Windows.UI.Xaml", "TreatAsAbstractComposableClassAttribute")) + treatment |= TypeDefinitionTreatment.Abstract; + } + else if (metadata_kind == MetadataKind.ManagedWindowsMetadata && IsClrImplementationType (type)) + treatment = TypeDefinitionTreatment.UnmangleWindowsRuntimeName; + + if (treatment != TypeDefinitionTreatment.None) + ApplyProjection (type, new TypeDefinitionProjection (type, treatment)); + } + + static TypeDefinitionTreatment GetWellKnownTypeDefinitionTreatment (TypeDefinition type) + { + ProjectionInfo info; + if (!Projections.TryGetValue (type.Name, out info)) + return TypeDefinitionTreatment.None; + + var treatment = info.Attribute ? TypeDefinitionTreatment.RedirectToClrAttribute : TypeDefinitionTreatment.RedirectToClrType; + + if (type.Namespace == info.ClrNamespace) + return treatment; + + if (type.Namespace == info.WinRTNamespace) + return treatment | TypeDefinitionTreatment.Internal; + + return TypeDefinitionTreatment.None; + } + + static bool NeedsWindowsRuntimePrefix (TypeDefinition type) + { + if ((type.Attributes & (TypeAttributes.VisibilityMask | TypeAttributes.Interface)) != TypeAttributes.Public) + return false; + + var base_type = type.BaseType; + if (base_type == null || base_type.MetadataToken.TokenType != TokenType.TypeRef) + return false; + + if (base_type.Namespace == "System") + switch (base_type.Name) + { + case "Attribute": + case "MulticastDelegate": + case "ValueType": + return false; + } + + return true; + } + + static bool IsClrImplementationType (TypeDefinition type) + { + if ((type.Attributes & (TypeAttributes.VisibilityMask | TypeAttributes.SpecialName)) != TypeAttributes.SpecialName) + return false; + return type.Name.StartsWith (""); + } + + public static void ApplyProjection (TypeDefinition type, TypeDefinitionProjection projection) + { + if (projection == null) + return; + + var treatment = projection.Treatment; + + switch (treatment & TypeDefinitionTreatment.KindMask) { + case TypeDefinitionTreatment.NormalType: + type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Import; + break; + + case TypeDefinitionTreatment.NormalAttribute: + type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Sealed; + break; + + case TypeDefinitionTreatment.UnmangleWindowsRuntimeName: + type.Attributes = type.Attributes & ~TypeAttributes.SpecialName | TypeAttributes.Public; + type.Name = type.Name.Substring ("".Length); + break; + + case TypeDefinitionTreatment.PrefixWindowsRuntimeName: + type.Attributes = type.Attributes & ~TypeAttributes.Public | TypeAttributes.Import; + type.Name = "" + type.Name; + break; + + case TypeDefinitionTreatment.RedirectToClrType: + type.Attributes = type.Attributes & ~TypeAttributes.Public | TypeAttributes.Import; + break; + + case TypeDefinitionTreatment.RedirectToClrAttribute: + type.Attributes = type.Attributes & ~TypeAttributes.Public; + break; + } + + if ((treatment & TypeDefinitionTreatment.Abstract) != 0) + type.Attributes |= TypeAttributes.Abstract; + + if ((treatment & TypeDefinitionTreatment.Internal) != 0) + type.Attributes &= ~TypeAttributes.Public; + + type.WindowsRuntimeProjection = projection; + } + + public static TypeDefinitionProjection RemoveProjection (TypeDefinition type) + { + if (!type.IsWindowsRuntimeProjection) + return null; + + var projection = type.WindowsRuntimeProjection; + type.WindowsRuntimeProjection = null; + + type.Attributes = projection.Attributes; + type.Name = projection.Name; + + return projection; + } + + public static void Project (TypeReference type) + { + TypeReferenceTreatment treatment; + + ProjectionInfo info; + if (Projections.TryGetValue (type.Name, out info) && info.WinRTNamespace == type.Namespace) + treatment = TypeReferenceTreatment.UseProjectionInfo; + else + treatment = GetSpecialTypeReferenceTreatment (type); + + if (treatment != TypeReferenceTreatment.None) + ApplyProjection (type, new TypeReferenceProjection (type, treatment)); + } + + static TypeReferenceTreatment GetSpecialTypeReferenceTreatment (TypeReference type) + { + if (type.Namespace == "System") { + if (type.Name == "MulticastDelegate") + return TypeReferenceTreatment.SystemDelegate; + if (type.Name == "Attribute") + return TypeReferenceTreatment.SystemAttribute; + } + + return TypeReferenceTreatment.None; + } + + static bool IsAttribute (TypeReference type) + { + if (type.MetadataToken.TokenType != TokenType.TypeRef) + return false; + return type.Name == "Attribute" && type.Namespace == "System"; + } + + static bool IsEnum (TypeReference type) + { + if (type.MetadataToken.TokenType != TokenType.TypeRef) + return false; + return type.Name == "Enum" && type.Namespace == "System"; + } + + public static void ApplyProjection (TypeReference type, TypeReferenceProjection projection) + { + if (projection == null) + return; + + switch (projection.Treatment) + { + case TypeReferenceTreatment.SystemDelegate: + case TypeReferenceTreatment.SystemAttribute: + type.Scope = type.Module.Projections.GetAssemblyReference ("System.Runtime"); + break; + + case TypeReferenceTreatment.UseProjectionInfo: + var info = Projections [type.Name]; + type.Name = info.ClrName; + type.Namespace = info.ClrNamespace; + type.Scope = type.Module.Projections.GetAssemblyReference (info.ClrAssembly); + break; + } + + type.WindowsRuntimeProjection = projection; + } + + public static TypeReferenceProjection RemoveProjection (TypeReference type) + { + if (!type.IsWindowsRuntimeProjection) + return null; + + var projection = type.WindowsRuntimeProjection; + type.WindowsRuntimeProjection = null; + + type.Name = projection.Name; + type.Namespace = projection.Namespace; + type.Scope = projection.Scope; + + return projection; + } + + public static void Project (MethodDefinition method) + { + var treatment = MethodDefinitionTreatment.None; + var other = false; + var declaring_type = method.DeclaringType; + + if (declaring_type.IsWindowsRuntime) + { + if (IsClrImplementationType (declaring_type)) + treatment = MethodDefinitionTreatment.None; + else if (declaring_type.IsNested) + treatment = MethodDefinitionTreatment.None; + else if (declaring_type.IsInterface) + treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall; + else if (declaring_type.Module.MetadataKind == MetadataKind.ManagedWindowsMetadata && !method.IsPublic) + treatment = MethodDefinitionTreatment.None; + else + { + other = true; + + var base_type = declaring_type.BaseType; + if (base_type != null && base_type.MetadataToken.TokenType == TokenType.TypeRef) + { + switch (GetSpecialTypeReferenceTreatment(base_type)) + { + case TypeReferenceTreatment.SystemDelegate: + treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.Public; + other = false; + break; + + case TypeReferenceTreatment.SystemAttribute: + treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall; + other = false; + break; + } + } + } + } + + if (other) + { + var seen_redirected = false; + var seen_non_redirected = false; + var disposable = false; + + foreach (var @override in method.Overrides) + { + if (@override.MetadataToken.TokenType == TokenType.MemberRef && ImplementsRedirectedInterface (@override, out disposable)) + { + seen_redirected = true; + if (disposable) + break; + } + else + seen_non_redirected = true; + } + + if (disposable) + { + treatment = MethodDefinitionTreatment.Dispose; + other = false; + } + else if (seen_redirected && !seen_non_redirected) + { + treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall | MethodDefinitionTreatment.Private; + other = false; + } + } + + if (other) + treatment |= GetMethodDefinitionTreatmentFromCustomAttributes(method); + + if (treatment != MethodDefinitionTreatment.None) + ApplyProjection (method, new MethodDefinitionProjection (method, treatment)); + } + + static MethodDefinitionTreatment GetMethodDefinitionTreatmentFromCustomAttributes(MethodDefinition method) + { + var treatment = MethodDefinitionTreatment.None; + + foreach (var attribute in method.CustomAttributes) + { + var type = attribute.AttributeType; + if (type.Namespace != "Windows.UI.Xaml") + continue; + if (type.Name == "TreatAsPublicMethodAttribute") + treatment |= MethodDefinitionTreatment.Public; + else if (type.Name == "TreatAsAbstractMethodAttribute") + treatment |= MethodDefinitionTreatment.Abstract; + } + + return treatment; + } + + public static void ApplyProjection (MethodDefinition method, MethodDefinitionProjection projection) + { + if (projection == null) + return; + + var treatment = projection.Treatment; + + if ((treatment & MethodDefinitionTreatment.Dispose) != 0) + method.Name = "Dispose"; + + if ((treatment & MethodDefinitionTreatment.Abstract) != 0) + method.Attributes |= MethodAttributes.Abstract; + + if ((treatment & MethodDefinitionTreatment.Private) != 0) + method.Attributes = (method.Attributes & ~MethodAttributes.MemberAccessMask) | MethodAttributes.Private; + + if ((treatment & MethodDefinitionTreatment.Public) != 0) + method.Attributes = (method.Attributes & ~MethodAttributes.MemberAccessMask) | MethodAttributes.Public; + + if ((treatment & MethodDefinitionTreatment.Runtime) != 0) + method.ImplAttributes |= MethodImplAttributes.Runtime; + + if ((treatment & MethodDefinitionTreatment.InternalCall) != 0) + method.ImplAttributes |= MethodImplAttributes.InternalCall; + + method.WindowsRuntimeProjection = projection; + } + + public static MethodDefinitionProjection RemoveProjection (MethodDefinition method) + { + if (!method.IsWindowsRuntimeProjection) + return null; + + var projection = method.WindowsRuntimeProjection; + method.WindowsRuntimeProjection = null; + + method.Attributes = projection.Attributes; + method.ImplAttributes = projection.ImplAttributes; + method.Name = projection.Name; + + return projection; + } + + public static void Project (FieldDefinition field) + { + var treatment = FieldDefinitionTreatment.None; + var declaring_type = field.DeclaringType; + + if (declaring_type.Module.MetadataKind == MetadataKind.WindowsMetadata && field.IsRuntimeSpecialName && field.Name == "value__") { + var base_type = declaring_type.BaseType; + if (base_type != null && IsEnum (base_type)) + treatment = FieldDefinitionTreatment.Public; + } + + if (treatment != FieldDefinitionTreatment.None) + ApplyProjection (field, new FieldDefinitionProjection (field, treatment)); + } + + public static void ApplyProjection (FieldDefinition field, FieldDefinitionProjection projection) + { + if (projection == null) + return; + + if (projection.Treatment == FieldDefinitionTreatment.Public) + field.Attributes = (field.Attributes & ~FieldAttributes.FieldAccessMask) | FieldAttributes.Public; + + field.WindowsRuntimeProjection = projection; + } + + public static FieldDefinitionProjection RemoveProjection (FieldDefinition field) + { + if (!field.IsWindowsRuntimeProjection) + return null; + + var projection = field.WindowsRuntimeProjection; + field.WindowsRuntimeProjection = null; + + field.Attributes = projection.Attributes; + + return projection; + } + + public static void Project (MemberReference member) + { + bool disposable; + if (!ImplementsRedirectedInterface (member, out disposable) || !disposable) + return; + + ApplyProjection (member, new MemberReferenceProjection (member, MemberReferenceTreatment.Dispose)); + } + + static bool ImplementsRedirectedInterface (MemberReference member, out bool disposable) + { + disposable = false; + + var declaring_type = member.DeclaringType; + TypeReference type; + switch (declaring_type.MetadataToken.TokenType) { + case TokenType.TypeRef: + type = declaring_type; + break; + + case TokenType.TypeSpec: + if (!declaring_type.IsGenericInstance) + return false; + + type = ((TypeSpecification) declaring_type).ElementType; + if (type.MetadataType != MetadataType.Class || type.MetadataToken.TokenType != TokenType.TypeRef) + return false; + + break; + + default: + return false; + } + + var projection = RemoveProjection (type); + + var found = false; + + ProjectionInfo info; + if (Projections.TryGetValue (type.Name, out info) && type.Namespace == info.WinRTNamespace) { + disposable = info.Disposable; + found = true; + } + + ApplyProjection (type, projection); + + return found; + } + + public static void ApplyProjection (MemberReference member, MemberReferenceProjection projection) + { + if (projection == null) + return; + + if (projection.Treatment == MemberReferenceTreatment.Dispose) + member.Name = "Dispose"; + + member.WindowsRuntimeProjection = projection; + } + + public static MemberReferenceProjection RemoveProjection (MemberReference member) + { + if (!member.IsWindowsRuntimeProjection) + return null; + + var projection = member.WindowsRuntimeProjection; + member.WindowsRuntimeProjection = null; + + member.Name = projection.Name; + + return projection; + } + + public void AddVirtualReferences (Collection references) + { + var corlib = GetCoreLibrary (references); + corlib_version = corlib.Version; + corlib.Version = version; + + if (virtual_references == null) { + var winrt_references = GetAssemblyReferences (corlib); + Interlocked.CompareExchange (ref virtual_references, winrt_references, null); + } + + foreach (var reference in virtual_references) + references.Add (reference); + } + + public void RemoveVirtualReferences (Collection references) + { + var corlib = GetCoreLibrary (references); + corlib.Version = corlib_version; + + foreach (var reference in VirtualReferences) + references.Remove (reference); + } + + static AssemblyNameReference[] GetAssemblyReferences (AssemblyNameReference corlib) + { + var system_runtime = new AssemblyNameReference ("System.Runtime", version); + var system_runtime_interopservices_windowsruntime = new AssemblyNameReference ("System.Runtime.InteropServices.WindowsRuntime", version); + var system_objectmodel = new AssemblyNameReference ("System.ObjectModel", version); + var system_runtime_windowsruntime = new AssemblyNameReference ("System.Runtime.WindowsRuntime", version); + var system_runtime_windowsruntime_ui_xaml = new AssemblyNameReference ("System.Runtime.WindowsRuntime.UI.Xaml", version); + var system_numerics_vectors = new AssemblyNameReference ("System.Numerics.Vectors", version); + + if (corlib.HasPublicKey) { + system_runtime_windowsruntime.PublicKey = + system_runtime_windowsruntime_ui_xaml.PublicKey = corlib.PublicKey; + + system_runtime.PublicKey = + system_runtime_interopservices_windowsruntime.PublicKey = + system_objectmodel.PublicKey = + system_numerics_vectors.PublicKey = contract_pk; + } + else { + system_runtime_windowsruntime.PublicKeyToken = + system_runtime_windowsruntime_ui_xaml.PublicKeyToken = corlib.PublicKeyToken; + + system_runtime.PublicKeyToken = + system_runtime_interopservices_windowsruntime.PublicKeyToken = + system_objectmodel.PublicKeyToken = + system_numerics_vectors.PublicKeyToken = contract_pk_token; + } + + return new[] { + system_runtime, + system_runtime_interopservices_windowsruntime, + system_objectmodel, + system_runtime_windowsruntime, + system_runtime_windowsruntime_ui_xaml, + system_numerics_vectors, + }; + } + + static AssemblyNameReference GetCoreLibrary (Collection references) + { + foreach (var reference in references) + if (reference.Name == "mscorlib") + return reference; + + throw new BadImageFormatException ("Missing mscorlib reference in AssemblyRef table."); + } + + AssemblyNameReference GetAssemblyReference (string name) + { + foreach (var assembly in VirtualReferences) + if (assembly.Name == name) + return assembly; + + throw new Exception (); + } + + public static void Project (ICustomAttributeProvider owner, CustomAttribute attribute) + { + if (!IsWindowsAttributeUsageAttribute (owner, attribute)) + return; + + var treatment = CustomAttributeValueTreatment.None; + var type = (TypeDefinition) owner; + + if (type.Namespace == "Windows.Foundation.Metadata") { + if (type.Name == "VersionAttribute") + treatment = CustomAttributeValueTreatment.VersionAttribute; + else if (type.Name == "DeprecatedAttribute") + treatment = CustomAttributeValueTreatment.DeprecatedAttribute; + } + + if (treatment == CustomAttributeValueTreatment.None) { + var multiple = HasAttribute (type, "Windows.Foundation.Metadata", "AllowMultipleAttribute"); + treatment = multiple ? CustomAttributeValueTreatment.AllowMultiple : CustomAttributeValueTreatment.AllowSingle; + } + + if (treatment != CustomAttributeValueTreatment.None) { + var attribute_targets = (AttributeTargets) attribute.ConstructorArguments [0].Value; + ApplyProjection (attribute, new CustomAttributeValueProjection (attribute_targets, treatment)); + } + } + + static bool IsWindowsAttributeUsageAttribute (ICustomAttributeProvider owner, CustomAttribute attribute) + { + if (owner.MetadataToken.TokenType != TokenType.TypeDef) + return false; + + var constructor = attribute.Constructor; + + if (constructor.MetadataToken.TokenType != TokenType.MemberRef) + return false; + + var declaring_type = constructor.DeclaringType; + + if (declaring_type.MetadataToken.TokenType != TokenType.TypeRef) + return false; + + // declaring type is already projected + return declaring_type.Name == "AttributeUsageAttribute" && declaring_type.Namespace == /*"Windows.Foundation.Metadata"*/"System"; + } + + static bool HasAttribute (TypeDefinition type, string @namespace, string name) + { + foreach (var attribute in type.CustomAttributes) { + var attribute_type = attribute.AttributeType; + if (attribute_type.Name == name && attribute_type.Namespace == @namespace) + return true; + } + return false; + } + + public static void ApplyProjection (CustomAttribute attribute, CustomAttributeValueProjection projection) + { + if (projection == null) + return; + + bool version_or_deprecated; + bool multiple; + + switch (projection.Treatment) { + case CustomAttributeValueTreatment.AllowSingle: + version_or_deprecated = false; + multiple = false; + break; + + case CustomAttributeValueTreatment.AllowMultiple: + version_or_deprecated = false; + multiple = true; + break; + + case CustomAttributeValueTreatment.VersionAttribute: + case CustomAttributeValueTreatment.DeprecatedAttribute: + version_or_deprecated = true; + multiple = true; + break; + + default: + throw new ArgumentException (); + } + + var attribute_targets = (AttributeTargets) attribute.ConstructorArguments [0].Value; + if (version_or_deprecated) + attribute_targets |= AttributeTargets.Constructor | AttributeTargets.Property; + attribute.ConstructorArguments [0] = new CustomAttributeArgument (attribute.ConstructorArguments [0].Type, attribute_targets); + + attribute.Properties.Add (new CustomAttributeNamedArgument ("AllowMultiple", new CustomAttributeArgument (attribute.Module.TypeSystem.Boolean, multiple))); + + attribute.projection = projection; + } + + public static CustomAttributeValueProjection RemoveProjection (CustomAttribute attribute) + { + if (attribute.projection == null) + return null; + + var projection = attribute.projection; + attribute.projection = null; + + attribute.ConstructorArguments [0] = new CustomAttributeArgument (attribute.ConstructorArguments [0].Type, projection.Targets); + attribute.Properties.Clear (); + + return projection; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/Collection.cs b/Mono.Cecil.20/Mono.Collections.Generic/Collection.cs similarity index 82% rename from Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/Collection.cs rename to Mono.Cecil.20/Mono.Collections.Generic/Collection.cs index 4d927176..015d271b 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/Collection.cs +++ b/Mono.Cecil.20/Mono.Collections.Generic/Collection.cs @@ -1,35 +1,19 @@ // -// Collection.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; using System.Collections; using System.Collections.Generic; +using Mono.Cecil; + namespace Mono.Collections.Generic { public class Collection : IList, IList { @@ -60,6 +44,16 @@ public T this [int index] { } } + public int Capacity { + get { return items.Length; } + set { + if (value < 0 || value < size) + throw new ArgumentOutOfRangeException (); + + Resize (value); + } + } + bool ICollection.IsReadOnly { get { return false; } } @@ -167,7 +161,6 @@ public void RemoveAt (int index) OnRemove (item, index); Shift (index, -1); - Array.Clear (items, size, 1); version++; } @@ -180,7 +173,6 @@ public bool Remove (T item) OnRemove (item, index); Shift (index, -1); - Array.Clear (items, size, 1); version++; return true; @@ -259,13 +251,17 @@ internal virtual void Grow (int desired) System.Math.Max (items.Length * 2, default_capacity), new_size); -#if !CF - Array.Resize (ref items, new_size); -#else - var array = new T [new_size]; - Array.Copy (items, array, size); - items = array; -#endif + Resize (new_size); + } + + protected void Resize (int new_size) + { + if (new_size == size) + return; + if (new_size < size) + throw new ArgumentOutOfRangeException (); + + items = items.Resize (new_size); } int IList.Add (object value) diff --git a/Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/ReadOnlyCollection.cs b/Mono.Cecil.20/Mono.Collections.Generic/ReadOnlyCollection.cs similarity index 57% rename from Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/ReadOnlyCollection.cs rename to Mono.Cecil.20/Mono.Collections.Generic/ReadOnlyCollection.cs index 7f24df69..fe784149 100644 --- a/Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/ReadOnlyCollection.cs +++ b/Mono.Cecil.20/Mono.Collections.Generic/ReadOnlyCollection.cs @@ -1,34 +1,16 @@ // -// ReadOnlyCollection.cs -// // Author: // Jb Evain (jbevain@gmail.com) // -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT/X11 license. // using System; using System.Collections; -using System .Collections.Generic; +using System.Collections.Generic; namespace Mono.Collections.Generic { @@ -52,7 +34,7 @@ bool IList.IsReadOnly { get { return true; } } - private ReadOnlyCollection () + ReadOnlyCollection () { } diff --git a/Mono.Cecil.20/Mono.Security.Cryptography/CryptoConvert.cs b/Mono.Cecil.20/Mono.Security.Cryptography/CryptoConvert.cs new file mode 100644 index 00000000..51f4ca13 --- /dev/null +++ b/Mono.Cecil.20/Mono.Security.Cryptography/CryptoConvert.cs @@ -0,0 +1,253 @@ +// +// CryptoConvert.cs - Crypto Convertion Routines +// +// Author: +// Sebastien Pouliot +// +// (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004-2006 Novell Inc. (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +#if !READ_ONLY + +#if !NET_CORE + +using System; +using System.Security.Cryptography; + +namespace Mono.Security.Cryptography { + + static class CryptoConvert { + + static private int ToInt32LE (byte [] bytes, int offset) + { + return (bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]; + } + + static private uint ToUInt32LE (byte [] bytes, int offset) + { + return (uint)((bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]); + } + + static private byte[] Trim (byte[] array) + { + for (int i=0; i < array.Length; i++) { + if (array [i] != 0x00) { + byte[] result = new byte [array.Length - i]; + Buffer.BlockCopy (array, i, result, 0, result.Length); + return result; + } + } + return null; + } + + static RSA FromCapiPrivateKeyBlob (byte[] blob, int offset) + { + RSAParameters rsap = new RSAParameters (); + try { + if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07) + (blob [offset+1] != 0x02) || // Version (0x02) + (blob [offset+2] != 0x00) || // Reserved (word) + (blob [offset+3] != 0x00) || + (ToUInt32LE (blob, offset+8) != 0x32415352)) // DWORD magic = RSA2 + throw new CryptographicException ("Invalid blob header"); + + // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) + // int algId = ToInt32LE (blob, offset+4); + + // DWORD bitlen + int bitLen = ToInt32LE (blob, offset+12); + + // DWORD public exponent + byte[] exp = new byte [4]; + Buffer.BlockCopy (blob, offset+16, exp, 0, 4); + Array.Reverse (exp); + rsap.Exponent = Trim (exp); + + int pos = offset+20; + // BYTE modulus[rsapubkey.bitlen/8]; + int byteLen = (bitLen >> 3); + rsap.Modulus = new byte [byteLen]; + Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); + Array.Reverse (rsap.Modulus); + pos += byteLen; + + // BYTE prime1[rsapubkey.bitlen/16]; + int byteHalfLen = (byteLen >> 1); + rsap.P = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen); + Array.Reverse (rsap.P); + pos += byteHalfLen; + + // BYTE prime2[rsapubkey.bitlen/16]; + rsap.Q = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen); + Array.Reverse (rsap.Q); + pos += byteHalfLen; + + // BYTE exponent1[rsapubkey.bitlen/16]; + rsap.DP = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen); + Array.Reverse (rsap.DP); + pos += byteHalfLen; + + // BYTE exponent2[rsapubkey.bitlen/16]; + rsap.DQ = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen); + Array.Reverse (rsap.DQ); + pos += byteHalfLen; + + // BYTE coefficient[rsapubkey.bitlen/16]; + rsap.InverseQ = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen); + Array.Reverse (rsap.InverseQ); + pos += byteHalfLen; + + // ok, this is hackish but CryptoAPI support it so... + // note: only works because CRT is used by default + // http://bugzilla.ximian.com/show_bug.cgi?id=57941 + rsap.D = new byte [byteLen]; // must be allocated + if (pos + byteLen + offset <= blob.Length) { + // BYTE privateExponent[rsapubkey.bitlen/8]; + Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen); + Array.Reverse (rsap.D); + } + } + catch (Exception e) { + throw new CryptographicException ("Invalid blob.", e); + } + + RSA rsa = null; + try { + rsa = RSA.Create (); + rsa.ImportParameters (rsap); + } + catch (CryptographicException) { + // this may cause problem when this code is run under + // the SYSTEM identity on Windows (e.g. ASP.NET). See + // http://bugzilla.ximian.com/show_bug.cgi?id=77559 + bool throws = false; + try { + CspParameters csp = new CspParameters (); + csp.Flags = CspProviderFlags.UseMachineKeyStore; + rsa = new RSACryptoServiceProvider (csp); + rsa.ImportParameters (rsap); + } + catch { + throws = true; + } + + if (throws) { + // rethrow original, not the latter, exception if this fails + throw; + } + } + return rsa; + } + + static RSA FromCapiPublicKeyBlob (byte[] blob, int offset) + { + try { + if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06) + (blob [offset+1] != 0x02) || // Version (0x02) + (blob [offset+2] != 0x00) || // Reserved (word) + (blob [offset+3] != 0x00) || + (ToUInt32LE (blob, offset+8) != 0x31415352)) // DWORD magic = RSA1 + throw new CryptographicException ("Invalid blob header"); + + // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) + // int algId = ToInt32LE (blob, offset+4); + + // DWORD bitlen + int bitLen = ToInt32LE (blob, offset+12); + + // DWORD public exponent + RSAParameters rsap = new RSAParameters (); + rsap.Exponent = new byte [3]; + rsap.Exponent [0] = blob [offset+18]; + rsap.Exponent [1] = blob [offset+17]; + rsap.Exponent [2] = blob [offset+16]; + + int pos = offset+20; + // BYTE modulus[rsapubkey.bitlen/8]; + int byteLen = (bitLen >> 3); + rsap.Modulus = new byte [byteLen]; + Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); + Array.Reverse (rsap.Modulus); + + RSA rsa = null; + try { + rsa = RSA.Create (); + rsa.ImportParameters (rsap); + } + catch (CryptographicException) { + // this may cause problem when this code is run under + // the SYSTEM identity on Windows (e.g. ASP.NET). See + // http://bugzilla.ximian.com/show_bug.cgi?id=77559 + CspParameters csp = new CspParameters (); + csp.Flags = CspProviderFlags.UseMachineKeyStore; + rsa = new RSACryptoServiceProvider (csp); + rsa.ImportParameters (rsap); + } + return rsa; + } + catch (Exception e) { + throw new CryptographicException ("Invalid blob.", e); + } + } + + // PRIVATEKEYBLOB + // PUBLICKEYBLOB + static public RSA FromCapiKeyBlob (byte[] blob) + { + return FromCapiKeyBlob (blob, 0); + } + + static public RSA FromCapiKeyBlob (byte[] blob, int offset) + { + if (blob == null) + throw new ArgumentNullException ("blob"); + if (offset >= blob.Length) + throw new ArgumentException ("blob is too small."); + + switch (blob [offset]) { + case 0x00: + // this could be a public key inside an header + // like "sn -e" would produce + if (blob [offset + 12] == 0x06) { + return FromCapiPublicKeyBlob (blob, offset + 12); + } + break; + case 0x06: + return FromCapiPublicKeyBlob (blob, offset); + case 0x07: + return FromCapiPrivateKeyBlob (blob, offset); + } + throw new CryptographicException ("Unknown blob format."); + } + } +} + +#endif + +#endif + diff --git a/Mono.Cecil.20/Mono.Security.Cryptography/CryptoService.cs b/Mono.Cecil.20/Mono.Security.Cryptography/CryptoService.cs new file mode 100644 index 00000000..840276d2 --- /dev/null +++ b/Mono.Cecil.20/Mono.Security.Cryptography/CryptoService.cs @@ -0,0 +1,158 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +#if !READ_ONLY + +#if !NET_CORE + +using System; +using System.IO; +using System.Reflection; +using System.Security.Cryptography; +using System.Runtime.Serialization; + +using Mono.Security.Cryptography; + +using Mono.Cecil.PE; + +namespace Mono.Cecil { + + // Most of this code has been adapted + // from Jeroen Frijters' fantastic work + // in IKVM.Reflection.Emit. Thanks! + + static class CryptoService { + + public static void StrongName (Stream stream, ImageWriter writer, StrongNameKeyPair key_pair) + { + int strong_name_pointer; + + var strong_name = CreateStrongName (key_pair, HashStream (stream, writer, out strong_name_pointer)); + PatchStrongName (stream, strong_name_pointer, strong_name); + } + + static void PatchStrongName (Stream stream, int strong_name_pointer, byte [] strong_name) + { + stream.Seek (strong_name_pointer, SeekOrigin.Begin); + stream.Write (strong_name, 0, strong_name.Length); + } + + static byte [] CreateStrongName (StrongNameKeyPair key_pair, byte [] hash) + { + const string hash_algo = "SHA1"; + + using (var rsa = key_pair.CreateRSA ()) { + var formatter = new RSAPKCS1SignatureFormatter (rsa); + formatter.SetHashAlgorithm (hash_algo); + + byte [] signature = formatter.CreateSignature (hash); + Array.Reverse (signature); + + return signature; + } + } + + static byte [] HashStream (Stream stream, ImageWriter writer, out int strong_name_pointer) + { + const int buffer_size = 8192; + + var text = writer.text; + var header_size = (int) writer.GetHeaderSize (); + var text_section_pointer = (int) text.PointerToRawData; + var strong_name_directory = writer.GetStrongNameSignatureDirectory (); + + if (strong_name_directory.Size == 0) + throw new InvalidOperationException (); + + strong_name_pointer = (int) (text_section_pointer + + (strong_name_directory.VirtualAddress - text.VirtualAddress)); + var strong_name_length = (int) strong_name_directory.Size; + + var sha1 = new SHA1Managed (); + var buffer = new byte [buffer_size]; + using (var crypto_stream = new CryptoStream (Stream.Null, sha1, CryptoStreamMode.Write)) { + + stream.Seek (0, SeekOrigin.Begin); + CopyStreamChunk (stream, crypto_stream, buffer, header_size); + + stream.Seek (text_section_pointer, SeekOrigin.Begin); + CopyStreamChunk (stream, crypto_stream, buffer, (int) strong_name_pointer - text_section_pointer); + + stream.Seek (strong_name_length, SeekOrigin.Current); + CopyStreamChunk (stream, crypto_stream, buffer, (int) (stream.Length - (strong_name_pointer + strong_name_length))); + } + + return sha1.Hash; + } + + static void CopyStreamChunk (Stream stream, Stream dest_stream, byte [] buffer, int length) + { + while (length > 0) { + int read = stream.Read (buffer, 0, System.Math.Min (buffer.Length, length)); + dest_stream.Write (buffer, 0, read); + length -= read; + } + } + + public static byte [] ComputeHash (string file) + { + if (!File.Exists (file)) + return Empty.Array; + + const int buffer_size = 8192; + + var sha1 = new SHA1Managed (); + + using (var stream = new FileStream (file, FileMode.Open, FileAccess.Read, FileShare.Read)) { + + var buffer = new byte [buffer_size]; + + using (var crypto_stream = new CryptoStream (Stream.Null, sha1, CryptoStreamMode.Write)) + CopyStreamChunk (stream, crypto_stream, buffer, (int) stream.Length); + } + + return sha1.Hash; + } + } + + static partial class Mixin { + + public static RSA CreateRSA (this StrongNameKeyPair key_pair) + { + byte [] key; + string key_container; + + if (!TryGetKeyContainer (key_pair, out key, out key_container)) + return CryptoConvert.FromCapiKeyBlob (key); + + var parameters = new CspParameters { + Flags = CspProviderFlags.UseMachineKeyStore, + KeyContainerName = key_container, + KeyNumber = 2, + }; + + return new RSACryptoServiceProvider (parameters); + } + + static bool TryGetKeyContainer (ISerializable key_pair, out byte [] key, out string key_container) + { + var info = new SerializationInfo (typeof (StrongNameKeyPair), new FormatterConverter ()); + key_pair.GetObjectData (info, new StreamingContext ()); + + key = (byte []) info.GetValue ("_keyPairArray", typeof (byte [])); + key_container = info.GetString ("_keyPairContainer"); + return key_container != null; + } + } +} + +#endif + +#endif diff --git a/Mono.Cecil.20/Mono/Disposable.cs b/Mono.Cecil.20/Mono/Disposable.cs new file mode 100644 index 00000000..dc2b1a3d --- /dev/null +++ b/Mono.Cecil.20/Mono/Disposable.cs @@ -0,0 +1,45 @@ +// +// 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; + +namespace Mono { + + static class Disposable { + + public static Disposable Owned (T value) where T : class, IDisposable + { + return new Disposable (value, owned: true); + } + + public static Disposable NotOwned (T value) where T : class, IDisposable + { + return new Disposable (value, owned: false); + } + } + + struct Disposable : IDisposable where T : class, IDisposable { + + internal readonly T value; + readonly bool owned; + + public Disposable (T value, bool owned) + { + this.value = value; + this.owned = owned; + } + + public void Dispose () + { + if (value != null && owned) + value.Dispose (); + } + } +} diff --git a/Mono.Cecil.20/Mono/Empty.cs b/Mono.Cecil.20/Mono/Empty.cs new file mode 100644 index 00000000..de28e656 --- /dev/null +++ b/Mono.Cecil.20/Mono/Empty.cs @@ -0,0 +1,62 @@ +// +// 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 Mono.Collections.Generic; + +namespace Mono { + + static class Empty { + + public static readonly T [] Array = new T [0]; + } + + class ArgumentNullOrEmptyException : ArgumentException { + + public ArgumentNullOrEmptyException (string paramName) + : base ("Argument null or empty", paramName) + { + } + } +} + +namespace Mono.Cecil { + + static partial class Mixin { + + public static bool IsNullOrEmpty (this T [] self) + { + return self == null || self.Length == 0; + } + + public static bool IsNullOrEmpty (this Collection self) + { + return self == null || self.size == 0; + } + + 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/Mono.Cecil.20/Mono/Type.cs b/Mono.Cecil.20/Mono/Type.cs new file mode 100644 index 00000000..4ff20483 --- /dev/null +++ b/Mono.Cecil.20/Mono/Type.cs @@ -0,0 +1,136 @@ +// +// 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.Reflection; + +#if NET_CORE +using System.Collections.Generic; +#endif + +namespace Mono { + +#if NET_CORE + enum TypeCode { + Empty = 0, + Object = 1, + DBNull = 2, + Boolean = 3, + Char = 4, + SByte = 5, + Byte = 6, + Int16 = 7, + UInt16 = 8, + Int32 = 9, + UInt32 = 10, + Int64 = 11, + UInt64 = 12, + Single = 13, + Double = 14, + Decimal = 15, + DateTime = 16, + String = 18 + } +#endif + + static class TypeExtensions { + +#if NET_CORE + private static readonly Dictionary TypeCodeMap = new Dictionary + { + { typeof (bool), TypeCode.Boolean }, + { typeof (char), TypeCode.Char }, + { typeof (sbyte), TypeCode.SByte }, + { typeof (byte), TypeCode.Byte }, + { typeof (short), TypeCode.Int16 }, + { typeof (ushort), TypeCode.UInt16 }, + { typeof (int), TypeCode.Int32 }, + { typeof (uint), TypeCode.UInt32 }, + { typeof (long), TypeCode.Int64 }, + { typeof (ulong), TypeCode.UInt64 }, + { typeof (float), TypeCode.Single }, + { typeof (double), TypeCode.Double }, + { typeof (decimal), TypeCode.Decimal }, + { typeof (DateTime), TypeCode.DateTime }, + { typeof (string), TypeCode.String }, + }; +#endif + + public static TypeCode GetTypeCode (this Type type) + { +#if NET_CORE + if (type == null) + return TypeCode.Empty; + + TypeCode code; + if (!TypeCodeMap.TryGetValue (type, out code)) + return TypeCode.Object; + + return code; +#else + return Type.GetTypeCode (type); +#endif + } + + public static Assembly Assembly (this Type type) + { +#if NET_CORE + return type.GetTypeInfo ().Assembly; +#else + return type.Assembly; +#endif + } + + public static MethodBase DeclaringMethod (this Type type) + { +#if NET_CORE + return type.GetTypeInfo ().DeclaringMethod; +#else + return type.DeclaringMethod; +#endif + } + + public static Type [] GetGenericArguments (this Type type) + { +#if NET_CORE + return type.GetTypeInfo ().GenericTypeArguments; +#else + return type.GetGenericArguments (); +#endif + } + + public static bool IsGenericType (this Type type) + { +#if NET_CORE + return type.GetTypeInfo ().IsGenericType; +#else + return type.IsGenericType; +#endif + } + + public static bool IsGenericTypeDefinition (this Type type) + { +#if NET_CORE + return type.GetTypeInfo ().IsGenericTypeDefinition; +#else + return type.IsGenericTypeDefinition; +#endif + } + + public static bool IsValueType (this Type type) + { +#if NET_CORE + return type.GetTypeInfo ().IsValueType; +#else + return type.IsValueType; +#endif + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeReader.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeReader.cs deleted file mode 100644 index fde16dec..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeReader.cs +++ /dev/null @@ -1,394 +0,0 @@ -// -// CodeReader.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using Mono.Cecil.PE; -using Mono.Collections.Generic; - -using RVA = System.UInt32; - -namespace Mono.Cecil.Cil -{ - - sealed class CodeReader : ByteBuffer - { - - readonly internal MetadataReader reader; - - int start; - Section code_section; - - MethodDefinition method; - MethodBody body; - - int Offset - { - get { return base.position - start; } - } - - public CodeReader(Section section, MetadataReader reader) - : base(section.Data) - { - this.code_section = section; - this.reader = reader; - } - - public MethodBody ReadMethodBody(MethodDefinition method) - { - this.method = method; - this.body = new MethodBody(method); - - reader.context = method; - - 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; - } - - void ReadMethodBody() - { - MoveTo(method.RVA); - - var flags = ReadByte(); - switch (flags & 0x3) - { - case 0x2: // tiny - body.code_size = flags >> 2; - body.MaxStackSize = 8; - ReadCode(); - break; - case 0x3: // fat - base.position--; - ReadFatMethod(); - break; - default: - throw new InvalidOperationException(); - } - - var symbol_reader = reader.module.symbol_reader; - - if (symbol_reader != null) - { - var instructions = body.Instructions; - symbol_reader.Read(body, offset => GetInstruction(instructions, offset)); - } - } - - void ReadFatMethod() - { - var flags = ReadUInt16(); - body.max_stack_size = ReadUInt16(); - body.code_size = (int)ReadUInt32(); - body.local_var_token = new MetadataToken(ReadUInt32()); - body.init_locals = (flags & 0x10) != 0; - - if (body.local_var_token.RID != 0) - body.variables = ReadVariables(body.local_var_token); - - ReadCode(); - - if ((flags & 0x8) != 0) - ReadSection(); - } - - public VariableDefinitionCollection ReadVariables(MetadataToken local_var_token) - { - var position = reader.position; - var variables = reader.ReadVariables(local_var_token); - reader.position = position; - - return variables; - } - - void ReadCode() - { - start = position; - var code_size = body.code_size; - - if (code_size < 0 || buffer.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; - var opcode = ReadOpCode(); - var current = new Instruction(offset, opcode); - - if (opcode.OperandType != OperandType.InlineNone) - current.operand = ReadOperand(current); - - instructions.Add(current); - } - - ResolveBranches(instructions); - } - - OpCode ReadOpCode() - { - var il_opcode = ReadByte(); - return il_opcode != 0xfe - ? OpCodes.OneByteOpCode[il_opcode] - : OpCodes.TwoBytesOpCode[ReadByte()]; - } - - object ReadOperand(Instruction instruction) - { - switch (instruction.opcode.OperandType) - { - case OperandType.InlineSwitch: - var length = ReadInt32(); - var base_offset = Offset + (4 * length); - var branches = new int[length]; - for (int i = 0; i < length; i++) - branches[i] = base_offset + ReadInt32(); - return branches; - case OperandType.ShortInlineBrTarget: - return ReadSByte() + Offset; - case OperandType.InlineBrTarget: - return ReadInt32() + Offset; - case OperandType.ShortInlineI: - if (instruction.opcode == OpCodes.Ldc_I4_S) - return ReadSByte(); - - return ReadByte(); - case OperandType.InlineI: - return ReadInt32(); - case OperandType.ShortInlineR: - return ReadSingle(); - case OperandType.InlineR: - return ReadDouble(); - case OperandType.InlineI8: - return ReadInt64(); - case OperandType.ShortInlineVar: - return GetVariable(ReadByte()); - case OperandType.InlineVar: - return GetVariable(ReadUInt16()); - case OperandType.ShortInlineArg: - return GetParameter(ReadByte()); - case OperandType.InlineArg: - return GetParameter(ReadUInt16()); - case OperandType.InlineSig: - return GetCallSite(ReadToken()); - case OperandType.InlineString: - return GetString(ReadToken()); - case OperandType.InlineTok: - case OperandType.InlineType: - case OperandType.InlineMethod: - case OperandType.InlineField: - return reader.LookupToken(ReadToken()); - default: - throw new NotSupportedException(); - } - } - - public string GetString(MetadataToken token) - { - return reader.image.UserStringHeap.Read(token.RID); - } - - public ParameterDefinition GetParameter(int index) - { - return Mixin.GetParameter(body, index); - } - - public VariableDefinition GetVariable(int index) - { - return Mixin.GetVariable(body, index); - } - - public CallSite GetCallSite(MetadataToken token) - { - return reader.ReadCallSite(token); - } - - void ResolveBranches(Collection instructions) - { - var items = instructions.items; - var size = instructions.size; - - for (int i = 0; i < size; i++) - { - var instruction = items[i]; - switch (instruction.opcode.OperandType) - { - case OperandType.ShortInlineBrTarget: - case OperandType.InlineBrTarget: - instruction.operand = GetInstruction((int)instruction.operand); - break; - case OperandType.InlineSwitch: - var offsets = (int[])instruction.operand; - var branches = new Instruction[offsets.Length]; - for (int j = 0; j < offsets.Length; j++) - branches[j] = GetInstruction(offsets[j]); - - instruction.operand = branches; - break; - } - } - } - - Instruction GetInstruction(int offset) - { - return GetInstruction(body.Instructions, offset); - } - - static Instruction GetInstruction(Collection instructions, int offset) - { - var size = instructions.size; - var items = instructions.items; - if (offset < 0 || offset > items[size - 1].offset) - return null; - - int min = 0; - int max = size - 1; - while (min <= max) - { - int mid = min + ((max - min) / 2); - var instruction = items[mid]; - var instruction_offset = instruction.offset; - - if (offset == instruction_offset) - return instruction; - - if (offset < instruction_offset) - max = mid - 1; - else - min = mid + 1; - } - - return null; - } - - void ReadSection() - { - Align(4); - - const byte fat_format = 0x40; - const byte more_sects = 0x80; - - var flags = ReadByte(); - if ((flags & fat_format) == 0) - ReadSmallSection(); - else - ReadFatSection(); - - if ((flags & more_sects) != 0) - ReadSection(); - } - - void ReadSmallSection() - { - var count = ReadByte() / 12; - Advance(2); - - ReadExceptionHandlers( - count, - () => (int)ReadUInt16(), - () => (int)ReadByte()); - } - - void ReadFatSection() - { - position--; - var count = (ReadInt32() >> 8) / 24; - - ReadExceptionHandlers( - count, - ReadInt32, - ReadInt32); - } - - // inline ? - void ReadExceptionHandlers(int count, Func read_entry, Func read_length) - { - for (int i = 0; i < count; i++) - { - var handler = new ExceptionHandler( - (ExceptionHandlerType)(read_entry() & 0x7)); - - handler.TryStart = GetInstruction(read_entry()); - handler.TryEnd = GetInstruction(handler.TryStart.Offset + read_length()); - - handler.HandlerStart = GetInstruction(read_entry()); - handler.HandlerEnd = GetInstruction(handler.HandlerStart.Offset + read_length()); - - ReadExceptionHandlerSpecific(handler); - - this.body.ExceptionHandlers.Add(handler); - } - } - - void ReadExceptionHandlerSpecific(ExceptionHandler handler) - { - switch (handler.HandlerType) - { - case ExceptionHandlerType.Catch: - handler.CatchType = (TypeReference)reader.LookupToken(ReadToken()); - break; - case ExceptionHandlerType.Filter: - handler.FilterStart = GetInstruction(ReadInt32()); - break; - default: - Advance(4); - break; - } - } - - void Align(int align) - { - align--; - Advance(((position + align) & ~align) - position); - } - - public MetadataToken ReadToken() - { - return new MetadataToken(ReadUInt32()); - } - - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeWriter.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeWriter.cs deleted file mode 100644 index 7c41343c..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeWriter.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// CodeWriter.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -using Mono.Collections.Generic; - -using Mono.Cecil.Metadata; -using Mono.Cecil.PE; - -using RVA = System.UInt32; - diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/MethodBody.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/MethodBody.cs deleted file mode 100644 index 29045cd4..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/MethodBody.cs +++ /dev/null @@ -1,267 +0,0 @@ -// -// MethodBody.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Threading; - -using Mono.Collections.Generic; - -namespace Mono.Cecil.Cil -{ - - public sealed class MethodBody : IVariableDefinitionProvider - { - - readonly internal MethodDefinition method; - - internal ParameterDefinition this_parameter; - internal int max_stack_size; - internal int code_size; - internal bool init_locals; - internal MetadataToken local_var_token; - - internal Collection instructions; - internal Collection exceptions; - internal Collection variables; - Scope scope; - - public MethodDefinition Method - { - get { return method; } - } - - public int MaxStackSize - { - get { return max_stack_size; } - set { max_stack_size = value; } - } - - public int CodeSize - { - get { return code_size; } - } - - public bool InitLocals - { - get { return init_locals; } - set { init_locals = value; } - } - - public MetadataToken LocalVarToken - { - get { return local_var_token; } - set { local_var_token = value; } - } - - public Collection Instructions - { - get { return instructions ?? (instructions = new InstructionCollection()); } - } - - public bool HasExceptionHandlers - { - get { return !Mixin.IsNullOrEmpty(exceptions); } - } - - public Collection ExceptionHandlers - { - get { return exceptions ?? (exceptions = new Collection()); } - } - - public bool HasVariables - { - get { return !Mixin.IsNullOrEmpty(variables); } - } - - 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) - throw new NotSupportedException(); - - if (!method.HasThis) - return null; - - if (this_parameter == null) - this_parameter = ThisParameterFor(method); - - return this_parameter; - } - } - - static ParameterDefinition ThisParameterFor(MethodDefinition method) - { - var declaring_type = method.DeclaringType; - var type = declaring_type.IsValueType || declaring_type.IsPrimitive - ? new PointerType(declaring_type) - : declaring_type as TypeReference; - - return new ParameterDefinition(type, method); - } - - public MethodBody(MethodDefinition method) - { - this.method = method; - } - - public ILProcessor GetILProcessor() - { - return new ILProcessor(this); - } - } - - public interface IVariableDefinitionProvider - { - bool HasVariables { get; } - Collection Variables { get; } - } - - class VariableDefinitionCollection : Collection - { - - internal VariableDefinitionCollection() - { - } - - internal VariableDefinitionCollection(int capacity) - : base(capacity) - { - } - - protected override void OnAdd(VariableDefinition item, int index) - { - item.index = index; - } - - protected override void OnInsert(VariableDefinition item, int index) - { - item.index = index; - - for (int i = index; i < size; i++) - items[i].index = i + 1; - } - - protected override void OnSet(VariableDefinition item, int index) - { - item.index = index; - } - - protected override void OnRemove(VariableDefinition item, int index) - { - item.index = -1; - - for (int i = index + 1; i < size; i++) - items[i].index = i - 1; - } - } - - class InstructionCollection : Collection - { - - internal InstructionCollection() - { - } - - internal InstructionCollection(int capacity) - : base(capacity) - { - } - - protected override void OnAdd(Instruction item, int index) - { - if (index == 0) - return; - - var previous = items[index - 1]; - previous.next = item; - item.previous = previous; - } - - protected override void OnInsert(Instruction item, int index) - { - if (size == 0) - return; - - var current = items[index]; - if (current == null) - { - var last = items[index - 1]; - last.next = item; - item.previous = last; - return; - } - - var previous = current.previous; - if (previous != null) - { - previous.next = item; - item.previous = previous; - } - - current.previous = item; - item.next = current; - } - - protected override void OnSet(Instruction item, int index) - { - var current = items[index]; - - item.previous = current.previous; - item.next = current.next; - - current.previous = null; - current.next = null; - } - - protected override void OnRemove(Instruction item, int index) - { - var previous = item.previous; - if (previous != null) - previous.next = item.next; - - var next = item.next; - if (next != null) - next.previous = item.previous; - - item.previous = null; - item.next = null; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/SequencePoint.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/SequencePoint.cs deleted file mode 100644 index ef87e30f..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/SequencePoint.cs +++ /dev/null @@ -1,70 +0,0 @@ -// -// SequencePoint.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil.Cil { - - public sealed class SequencePoint { - - Document document; - - int start_line; - int start_column; - int end_line; - int end_column; - - public int StartLine { - get { return start_line; } - set { start_line = value; } - } - - public int StartColumn { - get { return start_column; } - set { start_column = value; } - } - - public int EndLine { - get { return end_line; } - set { end_line = value; } - } - - public int EndColumn { - get { return end_column; } - set { end_column = value; } - } - - public Document Document { - get { return document; } - set { document = value; } - } - - public SequencePoint (Document document) - { - this.document = document; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Symbols.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Symbols.cs deleted file mode 100644 index 0774d9ca..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Symbols.cs +++ /dev/null @@ -1,243 +0,0 @@ -// -// Symbols.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using System.Runtime.InteropServices; -using SR = System.Reflection; - -using Mono.Collections.Generic; - -namespace Mono.Cecil.Cil { - - [StructLayout (LayoutKind.Sequential)] - public struct ImageDebugDirectory { - public int Characteristics; - public int TimeDateStamp; - public short MajorVersion; - public short MinorVersion; - public int Type; - public int SizeOfData; - public int AddressOfRawData; - public int PointerToRawData; - } - - public sealed class Scope : IVariableDefinitionProvider { - - Instruction start; - Instruction end; - - Collection scopes; - Collection variables; - - public Instruction Start { - get { return start; } - set { start = value; } - } - - public Instruction End { - get { return end; } - set { end = value; } - } - - public bool HasScopes { - get { return !Mixin.IsNullOrEmpty (scopes); } - } - - public Collection Scopes { - get { - if (scopes == null) - scopes = new Collection (); - - return scopes; - } - } - - public bool HasVariables { - get { return !Mixin.IsNullOrEmpty (variables); } - } - - public Collection Variables { - get { - if (variables == null) - variables = new Collection (); - - return variables; - } - } - } - - public struct InstructionSymbol { - - public readonly int Offset; - public readonly SequencePoint SequencePoint; - - public InstructionSymbol (int offset, SequencePoint sequencePoint) - { - this.Offset = offset; - this.SequencePoint = sequencePoint; - } - } - - public sealed class MethodSymbols { - - internal int code_size; - internal string method_name; - internal MetadataToken method_token; - internal MetadataToken local_var_token; - internal Collection variables; - public Collection instructions; - - public bool HasVariables { - get { return !Mixin.IsNullOrEmpty (variables); } - } - - public Collection Variables { - get { - if (variables == null) - variables = new Collection (); - - return variables; - } - } - - public Collection Instructions { - get { - if (instructions == null) - instructions = new Collection (); - - return instructions; - } - } - - public int CodeSize { - get { return code_size; } - } - - public string MethodName { - get { return method_name; } - } - - public MetadataToken MethodToken { - get { return method_token; } - } - - public MetadataToken LocalVarToken { - get { return local_var_token; } - } - - internal MethodSymbols (string methodName) - { - this.method_name = methodName; - } - - public MethodSymbols (MetadataToken methodToken) - { - this.method_token = methodToken; - } - } - - public delegate Instruction InstructionMapper (int offset); - - public interface ISymbolReader : IDisposable { - - bool ProcessDebugHeader (ImageDebugDirectory directory, byte [] header); - void Read (MethodBody body, InstructionMapper mapper); - void Read (MethodSymbols symbols); - } - - public interface ISymbolReaderProvider { - - ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName); - ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream); - } - - static class SymbolProvider { - - static readonly string symbol_kind = Type.GetType ("Mono.Runtime") != null ? "Mdb" : "Pdb"; - - static SR.AssemblyName GetPlatformSymbolAssemblyName () - { - var cecil_name = typeof (SymbolProvider).Assembly.GetName (); - - var name = new SR.AssemblyName { - Name = "Mono.Cecil." + symbol_kind, - Version = cecil_name.Version, - }; - - name.SetPublicKeyToken (cecil_name.GetPublicKeyToken ()); - - return name; - } - - static Type GetPlatformType (string fullname) - { - var type = Type.GetType (fullname); - if (type != null) - return type; - - var assembly_name = GetPlatformSymbolAssemblyName (); - - type = Type.GetType (fullname + ", " + assembly_name.FullName); - if (type != null) - return type; - - try { - var assembly = SR.Assembly.Load (assembly_name); - if (assembly != null) - return assembly.GetType (fullname); - } catch (FileNotFoundException) { - - } - - return null; - } - - static ISymbolReaderProvider reader_provider; - - public static ISymbolReaderProvider GetPlatformReaderProvider () - { - if (reader_provider != null) - return reader_provider; - - var type = GetPlatformType (GetProviderTypeName ("ReaderProvider")); - if (type == null) - return null; - - return reader_provider = (ISymbolReaderProvider) Activator.CreateInstance (type); - } - - static string GetProviderTypeName (string name) - { - return "Mono.Cecil." + symbol_kind + "." + symbol_kind + name; - } - - - } - -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableDefinition.cs deleted file mode 100644 index f501bca6..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableDefinition.cs +++ /dev/null @@ -1,52 +0,0 @@ -// -// VariableDefinition.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil.Cil { - - public sealed class VariableDefinition : VariableReference { - - public bool IsPinned { - get { return variable_type.IsPinned; } - } - - public VariableDefinition (TypeReference variableType) - : base (variableType) - { - } - - public VariableDefinition (string name, TypeReference variableType) - : base (name, variableType) - { - } - - public override VariableDefinition Resolve () - { - return this; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableReference.cs deleted file mode 100644 index ce0b4cdb..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableReference.cs +++ /dev/null @@ -1,75 +0,0 @@ -// -// VariableReference.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -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; } - } - - public int Index { - get { return 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; - } - - public abstract VariableDefinition Resolve (); - - public override string ToString () - { - if (!string.IsNullOrEmpty (name)) - return name; - - if (index >= 0) - return "V_" + index; - - return string.Empty; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/BlobHeap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/BlobHeap.cs deleted file mode 100644 index e19d0ced..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/BlobHeap.cs +++ /dev/null @@ -1,61 +0,0 @@ -// -// BlobHeap.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -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 byte[] Read(uint index) - { - if (index == 0 || index > Size - 1) - return Empty.Array; - - var data = Section.Data; - - int position = (int)(index + Offset); - int length = (int)Mixin.ReadCompressedUInt32(data, ref position); - - var buffer = new byte[length]; - - Buffer.BlockCopy(data, position, buffer, 0, length); - - return buffer; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Buffers.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Buffers.cs deleted file mode 100644 index 97b48d8b..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Buffers.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// TableHeapBuffer.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Text; - -using Mono.Cecil.PE; - -using RVA = System.UInt32; - diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/CodedIndex.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/CodedIndex.cs deleted file mode 100644 index 3e30fd87..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/CodedIndex.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// CodedIndex.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil.Metadata { - - enum CodedIndex { - TypeDefOrRef, - HasConstant, - HasCustomAttribute, - HasFieldMarshal, - HasDeclSecurity, - MemberRefParent, - HasSemantics, - MethodDefOrRef, - MemberForwarded, - Implementation, - CustomAttributeType, - ResolutionScope, - TypeOrMethodDef - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/GuidHeap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/GuidHeap.cs deleted file mode 100644 index 1adc0795..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/GuidHeap.cs +++ /dev/null @@ -1,59 +0,0 @@ -// -// GuidHeap.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -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 Guid Read (uint index) - { - if (index == 0) - return new Guid (); - - const int guid_size = 16; - - var buffer = new byte [guid_size]; - - index--; - - Buffer.BlockCopy (Section.Data, (int) (Offset + index), buffer, 0, guid_size); - - return new Guid (buffer); - - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Heap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Heap.cs deleted file mode 100644 index bc21acde..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Heap.cs +++ /dev/null @@ -1,48 +0,0 @@ -// -// Heap.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -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; - - protected Heap (Section section, uint offset, uint size) - { - this.Section = section; - this.Offset = offset; - this.Size = size; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/StringHeap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/StringHeap.cs deleted file mode 100644 index 4a0a0af4..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/StringHeap.cs +++ /dev/null @@ -1,81 +0,0 @@ -// -// StringHeap.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Text; - -using Mono.Cecil.PE; - -namespace Mono.Cecil.Metadata { - - class StringHeap : Heap { - - readonly Dictionary strings = new Dictionary (); - - public StringHeap (Section section, uint start, uint size) - : base (section, start, size) - { - } - - public string Read (uint index) - { - if (index == 0) - return string.Empty; - - string @string; - if (strings.TryGetValue (index, out @string)) - return @string; - - if (index > Size - 1) - return string.Empty; - - @string = ReadStringAt (index); - if (@string.Length != 0) - strings.Add (index, @string); - - return @string; - } - - protected virtual string ReadStringAt (uint index) - { - int length = 0; - byte [] data = Section.Data; - int start = (int) (index + Offset); - - for (int i = start; ; i++) { - if (data [i] == 0) - break; - - length++; - } - - return Encoding.UTF8.GetString (data, start, length); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TokenType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TokenType.cs deleted file mode 100644 index 2c2010ff..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TokenType.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// TokenType.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public enum TokenType : uint { - Module = 0x00000000, - TypeRef = 0x01000000, - TypeDef = 0x02000000, - Field = 0x04000000, - Method = 0x06000000, - Param = 0x08000000, - InterfaceImpl = 0x09000000, - MemberRef = 0x0a000000, - CustomAttribute = 0x0c000000, - Permission = 0x0e000000, - Signature = 0x11000000, - Event = 0x14000000, - Property = 0x17000000, - ModuleRef = 0x1a000000, - TypeSpec = 0x1b000000, - Assembly = 0x20000000, - AssemblyRef = 0x23000000, - File = 0x26000000, - ExportedType = 0x27000000, - ManifestResource = 0x28000000, - GenericParam = 0x2a000000, - MethodSpec = 0x2b000000, - String = 0x70000000, - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/UserStringHeap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/UserStringHeap.cs deleted file mode 100644 index 3d3c5b6f..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/UserStringHeap.cs +++ /dev/null @@ -1,61 +0,0 @@ -// -// UserStringHeap.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -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) - { - } - - protected override string ReadStringAt(uint index) - { - byte[] data = Section.Data; - int start = (int)(index + Offset); - - uint length = (uint)(Mixin.ReadCompressedUInt32(data, ref start) & ~1); - if (length < 1) - return string.Empty; - - var chars = new char[length / 2]; - - for (int i = start, j = 0; i < start + length; i += 2) - chars[j++] = (char)(data[i] | (data[i + 1] << 8)); - - return new string(chars); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Utilities.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Utilities.cs deleted file mode 100644 index 71200e3e..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Utilities.cs +++ /dev/null @@ -1,354 +0,0 @@ -// -// Utilities.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using Mono.Cecil.Metadata; - -namespace Mono.Cecil -{ - - static partial class Mixin - { - - public static uint ReadCompressedUInt32(byte[] data, ref int position) - { - uint integer; - if ((data[position] & 0x80) == 0) - { - integer = data[position]; - position++; - } - else if ((data[position] & 0x40) == 0) - { - integer = (uint)(data[position] & ~0x80) << 8; - integer |= data[position + 1]; - position += 2; - } - else - { - integer = (uint)(data[position] & ~0xc0) << 24; - integer |= (uint)data[position + 1] << 16; - integer |= (uint)data[position + 2] << 8; - integer |= (uint)data[position + 3]; - position += 4; - } - return integer; - } - - public static MetadataToken GetMetadataToken(CodedIndex self, uint data) - { - uint rid; - TokenType token_type; - switch (self) - { - case CodedIndex.TypeDefOrRef: - rid = data >> 2; - switch (data & 3) - { - case 0: - token_type = TokenType.TypeDef; goto ret; - case 1: - token_type = TokenType.TypeRef; goto ret; - case 2: - token_type = TokenType.TypeSpec; goto ret; - default: - goto exit; - } - case CodedIndex.HasConstant: - rid = data >> 2; - switch (data & 3) - { - case 0: - token_type = TokenType.Field; goto ret; - case 1: - token_type = TokenType.Param; goto ret; - case 2: - token_type = TokenType.Property; goto ret; - default: - goto exit; - } - case CodedIndex.HasCustomAttribute: - 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; - default: - goto exit; - } - case CodedIndex.HasFieldMarshal: - rid = data >> 1; - switch (data & 1) - { - case 0: - token_type = TokenType.Field; goto ret; - case 1: - token_type = TokenType.Param; goto ret; - default: - goto exit; - } - case CodedIndex.HasDeclSecurity: - rid = data >> 2; - switch (data & 3) - { - case 0: - token_type = TokenType.TypeDef; goto ret; - case 1: - token_type = TokenType.Method; goto ret; - case 2: - token_type = TokenType.Assembly; goto ret; - default: - goto exit; - } - case CodedIndex.MemberRefParent: - rid = data >> 3; - switch (data & 7) - { - case 0: - token_type = TokenType.TypeDef; goto ret; - case 1: - token_type = TokenType.TypeRef; goto ret; - case 2: - token_type = TokenType.ModuleRef; goto ret; - case 3: - token_type = TokenType.Method; goto ret; - case 4: - token_type = TokenType.TypeSpec; goto ret; - default: - goto exit; - } - case CodedIndex.HasSemantics: - rid = data >> 1; - switch (data & 1) - { - case 0: - token_type = TokenType.Event; goto ret; - case 1: - token_type = TokenType.Property; goto ret; - default: - goto exit; - } - case CodedIndex.MethodDefOrRef: - rid = data >> 1; - switch (data & 1) - { - case 0: - token_type = TokenType.Method; goto ret; - case 1: - token_type = TokenType.MemberRef; goto ret; - default: - goto exit; - } - case CodedIndex.MemberForwarded: - rid = data >> 1; - switch (data & 1) - { - case 0: - token_type = TokenType.Field; goto ret; - case 1: - token_type = TokenType.Method; goto ret; - default: - goto exit; - } - case CodedIndex.Implementation: - rid = data >> 2; - switch (data & 3) - { - case 0: - token_type = TokenType.File; goto ret; - case 1: - token_type = TokenType.AssemblyRef; goto ret; - case 2: - token_type = TokenType.ExportedType; goto ret; - default: - goto exit; - } - case CodedIndex.CustomAttributeType: - rid = data >> 3; - switch (data & 7) - { - case 2: - token_type = TokenType.Method; goto ret; - case 3: - token_type = TokenType.MemberRef; goto ret; - default: - goto exit; - } - case CodedIndex.ResolutionScope: - rid = data >> 2; - switch (data & 3) - { - case 0: - token_type = TokenType.Module; goto ret; - case 1: - token_type = TokenType.ModuleRef; goto ret; - case 2: - token_type = TokenType.AssemblyRef; goto ret; - case 3: - token_type = TokenType.TypeRef; goto ret; - default: - goto exit; - } - case CodedIndex.TypeOrMethodDef: - rid = data >> 1; - switch (data & 1) - { - case 0: - token_type = TokenType.TypeDef; goto ret; - case 1: - token_type = TokenType.Method; goto ret; - default: goto exit; - } - default: - goto exit; - } - ret: - return new MetadataToken(token_type, rid); - exit: - return MetadataToken.Zero; - } - - - public static int GetSize(CodedIndex self, Func counter) - { - int bits; - Table[] tables; - - switch (self) - { - case CodedIndex.TypeDefOrRef: - bits = 2; - tables = new[] { Table.TypeDef, Table.TypeRef, Table.TypeSpec }; - break; - case CodedIndex.HasConstant: - bits = 2; - tables = new[] { Table.Field, Table.Param, Table.Property }; - break; - case CodedIndex.HasCustomAttribute: - 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 - }; - break; - case CodedIndex.HasFieldMarshal: - bits = 1; - tables = new[] { Table.Field, Table.Param }; - break; - case CodedIndex.HasDeclSecurity: - bits = 2; - tables = new[] { Table.TypeDef, Table.Method, Table.Assembly }; - break; - case CodedIndex.MemberRefParent: - bits = 3; - tables = new[] { Table.TypeDef, Table.TypeRef, Table.ModuleRef, Table.Method, Table.TypeSpec }; - break; - case CodedIndex.HasSemantics: - bits = 1; - tables = new[] { Table.Event, Table.Property }; - break; - case CodedIndex.MethodDefOrRef: - bits = 1; - tables = new[] { Table.Method, Table.MemberRef }; - break; - case CodedIndex.MemberForwarded: - bits = 1; - tables = new[] { Table.Field, Table.Method }; - break; - case CodedIndex.Implementation: - bits = 2; - tables = new[] { Table.File, Table.AssemblyRef, Table.ExportedType }; - break; - case CodedIndex.CustomAttributeType: - bits = 3; - tables = new[] { Table.Method, Table.MemberRef }; - break; - case CodedIndex.ResolutionScope: - bits = 2; - tables = new[] { Table.Module, Table.ModuleRef, Table.AssemblyRef, Table.TypeRef }; - break; - case CodedIndex.TypeOrMethodDef: - bits = 1; - tables = new[] { Table.TypeDef, Table.Method }; - break; - default: - throw new ArgumentException(); - } - - int max = 0; - - for (int i = 0; i < tables.Length; i++) - { - max = System.Math.Max(counter(tables[i]), max); - } - - return max < (1 << (16 - bits)) ? 2 : 4; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamReader.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamReader.cs deleted file mode 100644 index ec2477c3..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamReader.cs +++ /dev/null @@ -1,51 +0,0 @@ -// -// BinaryStreamReader.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace Mono.Cecil.PE { - - class BinaryStreamReader : BinaryReader { - - public BinaryStreamReader (Stream stream) - : base (stream) - { - } - - protected void Advance (int bytes) - { - BaseStream.Seek (bytes, SeekOrigin.Current); - } - - protected DataDirectory ReadDataDirectory () - { - return new DataDirectory (ReadUInt32 (), ReadUInt32 ()); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamWriter.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamWriter.cs deleted file mode 100644 index 00a79755..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamWriter.cs +++ /dev/null @@ -1,31 +0,0 @@ -// -// BinaryStreamWriter.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBuffer.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBuffer.cs deleted file mode 100644 index a09812aa..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBuffer.cs +++ /dev/null @@ -1,184 +0,0 @@ -// -// ByteBuffer.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil.PE { - - class ByteBuffer { - - internal byte [] buffer; - internal int length; - internal int position; - - public ByteBuffer () - { - this.buffer = Empty.Array; - } - - public ByteBuffer (int length) - { - this.buffer = new byte [length]; - } - - public ByteBuffer (byte [] buffer) - { - this.buffer = buffer ?? Empty.Array; - this.length = this.buffer.Length; - } - - public void Reset (byte [] buffer) - { - this.buffer = buffer ?? Empty.Array; - this.length = this.buffer.Length; - } - - public void Advance (int length) - { - position += length; - } - - public byte ReadByte () - { - return buffer [position++]; - } - - public sbyte ReadSByte () - { - return (sbyte) ReadByte (); - } - - public byte [] ReadBytes (int length) - { - var bytes = new byte [length]; - Buffer.BlockCopy (buffer, position, bytes, 0, length); - position += length; - return bytes; - } - - public ushort ReadUInt16 () - { - ushort value = (ushort) (buffer [position] - | (buffer [position + 1] << 8)); - position += 2; - return value; - } - - public short ReadInt16 () - { - return (short) ReadUInt16 (); - } - - public uint ReadUInt32 () - { - uint value = (uint) (buffer [position] - | (buffer [position + 1] << 8) - | (buffer [position + 2] << 16) - | (buffer [position + 3] << 24)); - position += 4; - return value; - } - - public int ReadInt32 () - { - return (int) ReadUInt32 (); - } - - public ulong ReadUInt64 () - { - uint low = ReadUInt32 (); - uint high = ReadUInt32 (); - - return (((ulong) high) << 32) | low; - } - - public long ReadInt64 () - { - return (long) ReadUInt64 (); - } - - public uint ReadCompressedUInt32 () - { - byte first = ReadByte (); - if ((first & 0x80) == 0) - return first; - - if ((first & 0x40) == 0) - return ((uint) (first & ~0x80) << 8) - | ReadByte (); - - return ((uint) (first & ~0xc0) << 24) - | (uint) ReadByte () << 16 - | (uint) ReadByte () << 8 - | ReadByte (); - } - - 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; - } - - public float ReadSingle () - { - if (!BitConverter.IsLittleEndian) { - var bytes = ReadBytes (4); - Array.Reverse (bytes); - return BitConverter.ToSingle (bytes, 0); - } - - float value = BitConverter.ToSingle (buffer, position); - position += 4; - return value; - } - - public double ReadDouble () - { - if (!BitConverter.IsLittleEndian) { - var bytes = ReadBytes (8); - Array.Reverse (bytes); - return BitConverter.ToDouble (bytes, 0); - } - - double value = BitConverter.ToDouble (buffer, position); - position += 8; - return value; - } - - - - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBufferEqualityComparer.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBufferEqualityComparer.cs deleted file mode 100644 index 70e89164..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBufferEqualityComparer.cs +++ /dev/null @@ -1,78 +0,0 @@ -// -// ByteBufferEqualityComparer.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -namespace Mono.Cecil.PE { - - sealed class ByteBufferEqualityComparer : IEqualityComparer { - - public bool Equals (ByteBuffer x, ByteBuffer y) - { - if (x.length != y.length) - return false; - - var x_buffer = x.buffer; - var y_buffer = y.buffer; - - for (int i = 0; i < x.length; i++) - if (x_buffer [i] != y_buffer [i]) - return false; - - return true; - } - - public int GetHashCode (ByteBuffer buffer) - { -#if !BYTE_BUFFER_WELL_DISTRIBUTED_HASH - var hash = 0; - var bytes = buffer.buffer; - for (int i = 0; i < buffer.length; i++) - hash = (hash * 37) ^ bytes [i]; - - return hash; -#else - const uint p = 16777619; - uint hash = 2166136261; - - var bytes = buffer.buffer; - for (int i = 0; i < buffer.length; i++) - hash = (hash ^ bytes [i]) * p; - - hash += hash << 13; - hash ^= hash >> 7; - hash += hash << 3; - hash ^= hash >> 17; - hash += hash << 5; - - return (int) hash; -#endif - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/DataDirectory.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/DataDirectory.cs deleted file mode 100644 index fedd0e2d..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/DataDirectory.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -// DataDirectory.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using RVA = System.UInt32; - -namespace Mono.Cecil.PE { - - struct DataDirectory { - - public readonly RVA VirtualAddress; - public readonly uint Size; - - public bool IsZero { - get { return VirtualAddress == 0 && Size == 0; } - } - - public DataDirectory (RVA rva, uint size) - { - this.VirtualAddress = rva; - this.Size = size; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Image.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Image.cs deleted file mode 100644 index 62b8d9f7..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Image.cs +++ /dev/null @@ -1,166 +0,0 @@ -// -// Image.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using Mono; -using Mono.Cecil.Cil; -using Mono.Cecil.Metadata; - -using RVA = System.UInt32; - -namespace Mono.Cecil.PE -{ - - sealed class Image - { - - public ModuleKind Kind; - public TargetRuntime Runtime; - public TargetArchitecture Architecture; - public ModuleCharacteristics Characteristics; - public string FileName; - - public Section[] Sections; - - public Section MetadataSection; - - public uint EntryPointToken; - public ModuleAttributes Attributes; - - public DataDirectory Debug; - public DataDirectory Resources; - public DataDirectory StrongName; - - public StringHeap StringHeap; - public BlobHeap BlobHeap; - public UserStringHeap UserStringHeap; - public GuidHeap GuidHeap; - public TableHeap TableHeap; - - readonly int[] coded_index_sizes = new int[13]; - - readonly Func counter; - - public Image() - { - counter = GetTableLength; - } - - public bool HasTable(Table table) - { - return GetTableLength(table) > 0; - } - - public int GetTableLength(Table table) - { - return (int)TableHeap[table].Length; - } - - public int GetTableIndexSize(Table table) - { - return GetTableLength(table) < 65536 ? 2 : 4; - } - - public int GetCodedIndexSize(CodedIndex coded_index) - { - var index = (int)coded_index; - var size = coded_index_sizes[index]; - if (size != 0) - return size; - - return coded_index_sizes[index] = Mixin.GetSize(coded_index, counter); - } - - public uint ResolveVirtualAddress(RVA rva) - { - var section = GetSectionAtVirtualAddress(rva); - if (section == null) - throw new ArgumentOutOfRangeException(); - - return ResolveVirtualAddressInSection(rva, section); - } - - public uint ResolveVirtualAddressInSection(RVA rva, Section section) - { - return rva + section.PointerToRawData - section.VirtualAddress; - } - - public Section GetSection(string name) - { - var sections = this.Sections; - for (int i = 0; i < sections.Length; i++) - { - var section = sections[i]; - if (section.Name == name) - return section; - } - - return null; - } - - public Section GetSectionAtVirtualAddress(RVA rva) - { - var sections = this.Sections; - for (int i = 0; i < sections.Length; i++) - { - var section = sections[i]; - if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.SizeOfRawData) - return section; - } - - return null; - } - - public ImageDebugDirectory GetDebugHeader(out byte[] header) - { - var section = GetSectionAtVirtualAddress(Debug.VirtualAddress); - var buffer = new ByteBuffer(section.Data); - buffer.position = (int)(Debug.VirtualAddress - section.VirtualAddress); - - 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(), - }; - - buffer.position = (int)(directory.PointerToRawData - section.PointerToRawData); - - header = new byte[directory.SizeOfData]; - Buffer.BlockCopy(buffer.buffer, buffer.position, header, 0, header.Length); - - return directory; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageReader.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageReader.cs deleted file mode 100644 index 00d0c672..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageReader.cs +++ /dev/null @@ -1,694 +0,0 @@ -// -// ImageReader.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -using Mono.Cecil.Metadata; - -using RVA = System.UInt32; - -namespace Mono.Cecil.PE -{ - - sealed class ImageReader : BinaryStreamReader - { - - readonly Image image; - - DataDirectory cli; - DataDirectory metadata; - - public ImageReader(Stream stream) - : base(stream) - { - image = new Image(); - - image.FileName = Mixin.GetFullyQualifiedName(stream); - } - - void MoveTo(DataDirectory directory) - { - BaseStream.Position = image.ResolveVirtualAddress(directory.VirtualAddress); - } - - void MoveTo(uint position) - { - BaseStream.Position = position; - } - - void ReadImage() - { - if (BaseStream.Length < 128) - throw new BadImageFormatException(); - - // - DOSHeader - - // PE 2 - // Start 58 - // Lfanew 4 - // End 64 - - if (ReadUInt16() != 0x5a4d) - throw new BadImageFormatException(); - - Advance(58); - - MoveTo(ReadUInt32()); - - if (ReadUInt32() != 0x00004550) - throw new BadImageFormatException(); - - // - PEFileHeader - - // Machine 2 - image.Architecture = ReadArchitecture(); - - // NumberOfSections 2 - ushort sections = ReadUInt16(); - - // TimeDateStamp 4 - // PointerToSymbolTable 4 - // NumberOfSymbols 4 - // OptionalHeaderSize 2 - Advance(14); - - // Characteristics 2 - ushort characteristics = ReadUInt16(); - - ushort subsystem, dll_characteristics; - ReadOptionalHeaders(out subsystem, out dll_characteristics); - ReadSections(sections); - ReadCLIHeader(); - ReadMetadata(); - - image.Kind = GetModuleKind(characteristics, subsystem); - image.Characteristics = (ModuleCharacteristics)dll_characteristics; - } - - TargetArchitecture ReadArchitecture() - { - var machine = ReadUInt16(); - switch (machine) - { - case 0x014c: - return TargetArchitecture.I386; - case 0x8664: - return TargetArchitecture.AMD64; - case 0x0200: - return TargetArchitecture.IA64; - case 0x01c4: - return TargetArchitecture.ARMv7; - } - - throw new NotSupportedException(); - } - - static ModuleKind GetModuleKind(ushort characteristics, ushort subsystem) - { - if ((characteristics & 0x2000) != 0) // ImageCharacteristics.Dll - return ModuleKind.Dll; - - if (subsystem == 0x2 || subsystem == 0x9) // SubSystem.WindowsGui || SubSystem.WindowsCeGui - return ModuleKind.Windows; - - return ModuleKind.Console; - } - - void ReadOptionalHeaders(out ushort subsystem, out ushort dll_characteristics) - { - // - PEOptionalHeader - // - StandardFieldsHeader - - // Magic 2 - bool pe64 = ReadUInt16() == 0x20b; - - // pe32 || pe64 - - // LMajor 1 - // LMinor 1 - // CodeSize 4 - // InitializedDataSize 4 - // UninitializedDataSize4 - // EntryPointRVA 4 - // BaseOfCode 4 - // BaseOfData 4 || 0 - - // - NTSpecificFieldsHeader - - // ImageBase 4 || 8 - // SectionAlignment 4 - // FileAlignement 4 - // OSMajor 2 - // OSMinor 2 - // UserMajor 2 - // UserMinor 2 - // SubSysMajor 2 - // SubSysMinor 2 - // Reserved 4 - // ImageSize 4 - // HeaderSize 4 - // FileChecksum 4 - Advance(66); - - // SubSystem 2 - subsystem = ReadUInt16(); - - // DLLFlags 2 - dll_characteristics = ReadUInt16(); - // StackReserveSize 4 || 8 - // StackCommitSize 4 || 8 - // HeapReserveSize 4 || 8 - // HeapCommitSize 4 || 8 - // LoaderFlags 4 - // NumberOfDataDir 4 - - // - DataDirectoriesHeader - - // ExportTable 8 - // ImportTable 8 - // ResourceTable 8 - // ExceptionTable 8 - // CertificateTable 8 - // BaseRelocationTable 8 - - Advance(pe64 ? 88 : 72); - - // Debug 8 - image.Debug = ReadDataDirectory(); - - // Copyright 8 - // GlobalPtr 8 - // TLSTable 8 - // LoadConfigTable 8 - // BoundImport 8 - // IAT 8 - // DelayImportDescriptor8 - Advance(56); - - // CLIHeader 8 - cli = ReadDataDirectory(); - - if (cli.IsZero) - throw new BadImageFormatException(); - - // Reserved 8 - Advance(8); - } - - string ReadAlignedString(int length) - { - int read = 0; - var buffer = new char[length]; - while (read < length) - { - var current = ReadByte(); - if (current == 0) - break; - - buffer[read++] = (char)current; - } - - Advance(-1 + ((read + 4) & ~3) - read); - - return new string(buffer, 0, read); - } - - string ReadZeroTerminatedString(int length) - { - int read = 0; - var buffer = new char[length]; - var bytes = ReadBytes(length); - while (read < length) - { - var current = bytes[read]; - if (current == 0) - break; - - buffer[read++] = (char)current; - } - - return new string(buffer, 0, read); - } - - void ReadSections(ushort count) - { - var sections = new Section[count]; - - for (int i = 0; i < count; i++) - { - var section = new Section(); - - // Name - section.Name = ReadZeroTerminatedString(8); - - // VirtualSize 4 - Advance(4); - - // VirtualAddress 4 - section.VirtualAddress = ReadUInt32(); - // SizeOfRawData 4 - section.SizeOfRawData = ReadUInt32(); - // PointerToRawData 4 - section.PointerToRawData = ReadUInt32(); - - // PointerToRelocations 4 - // PointerToLineNumbers 4 - // NumberOfRelocations 2 - // NumberOfLineNumbers 2 - // Characteristics 4 - 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); - - // - CLIHeader - - // Cb 4 - // MajorRuntimeVersion 2 - // MinorRuntimeVersion 2 - Advance(8); - - // Metadata 8 - metadata = ReadDataDirectory(); - // Flags 4 - image.Attributes = (ModuleAttributes)ReadUInt32(); - // EntryPointToken 4 - image.EntryPointToken = ReadUInt32(); - // Resources 8 - image.Resources = ReadDataDirectory(); - // StrongNameSignature 8 - image.StrongName = ReadDataDirectory(); - // CodeManagerTable 8 - // VTableFixups 8 - // ExportAddressTableJumps 8 - // ManagedNativeHeader 8 - } - - void ReadMetadata() - { - MoveTo(metadata); - - if (ReadUInt32() != 0x424a5342) - throw new BadImageFormatException(); - - // MajorVersion 2 - // MinorVersion 2 - // Reserved 4 - Advance(8); - - var version = ReadZeroTerminatedString(ReadInt32()); - image.Runtime = Mixin.ParseRuntime(version); - - // Flags 2 - Advance(2); - - var streams = ReadUInt16(); - - var section = image.GetSectionAtVirtualAddress(metadata.VirtualAddress); - if (section == null) - throw new BadImageFormatException(); - - image.MetadataSection = section; - - for (int i = 0; i < streams; i++) - ReadMetadataStream(section); - - if (image.TableHeap != null) - ReadTableHeap(); - } - - void ReadMetadataStream(Section section) - { - // Offset 4 - uint start = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32(); // relative to the section start - - // Size 4 - uint size = ReadUInt32(); - - var name = ReadAlignedString(16); - switch (name) - { - case "#~": - case "#-": - image.TableHeap = new TableHeap(section, start, size); - break; - case "#Strings": - image.StringHeap = new StringHeap(section, start, size); - break; - case "#Blob": - image.BlobHeap = new BlobHeap(section, start, size); - break; - case "#GUID": - image.GuidHeap = new GuidHeap(section, start, size); - break; - case "#US": - image.UserStringHeap = new UserStringHeap(section, start, size); - break; - } - } - - void ReadTableHeap() - { - var heap = image.TableHeap; - - uint start = heap.Section.PointerToRawData; - - MoveTo(heap.Offset + start); - - // Reserved 4 - // MajorVersion 1 - // MinorVersion 1 - Advance(6); - - // HeapSizes 1 - var sizes = ReadByte(); - - // Reserved2 1 - Advance(1); - - // Valid 8 - heap.Valid = ReadInt64(); - - // Sorted 8 - heap.Sorted = ReadInt64(); - - for (int i = 0; i < TableHeap.TableCount; i++) - { - if (!heap.HasTable((Table)i)) - continue; - - heap.Tables[i].Length = ReadUInt32(); - } - - SetIndexSize(image.StringHeap, sizes, 0x1); - SetIndexSize(image.GuidHeap, sizes, 0x2); - SetIndexSize(image.BlobHeap, sizes, 0x4); - - ComputeTableInformations(); - } - - static void SetIndexSize(Heap heap, uint sizes, byte flag) - { - if (heap == null) - return; - - heap.IndexSize = (sizes & flag) > 0 ? 4 : 2; - } - - int GetTableIndexSize(Table table) - { - return image.GetTableIndexSize(table); - } - - int GetCodedIndexSize(CodedIndex index) - { - return image.GetCodedIndexSize(index); - } - - void ComputeTableInformations() - { - uint offset = (uint)BaseStream.Position - image.MetadataSection.PointerToRawData; // header - - int stridx_size = image.StringHeap.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++) - { - var table = (Table)i; - if (!heap.HasTable(table)) - continue; - - int size; - switch (table) - { - case Table.Module: - size = 2 // Generation - + stridx_size // Name - + (image.GuidHeap.IndexSize * 3); // Mvid, EncId, EncBaseId - break; - case Table.TypeRef: - size = GetCodedIndexSize(CodedIndex.ResolutionScope) // ResolutionScope - + (stridx_size * 2); // Name, Namespace - break; - case Table.TypeDef: - size = 4 // Flags - + (stridx_size * 2) // Name, Namespace - + GetCodedIndexSize(CodedIndex.TypeDefOrRef) // BaseType - + GetTableIndexSize(Table.Field) // FieldList - + GetTableIndexSize(Table.Method); // MethodList - break; - case Table.FieldPtr: - size = GetTableIndexSize(Table.Field); // Field - break; - case Table.Field: - size = 2 // Flags - + stridx_size // Name - + blobidx_size; // Signature - break; - case Table.MethodPtr: - size = GetTableIndexSize(Table.Method); // Method - break; - case Table.Method: - size = 8 // Rva 4, ImplFlags 2, Flags 2 - + stridx_size // Name - + blobidx_size // Signature - + GetTableIndexSize(Table.Param); // ParamList - break; - case Table.ParamPtr: - size = GetTableIndexSize(Table.Param); // Param - break; - case Table.Param: - size = 4 // Flags 2, Sequence 2 - + stridx_size; // Name - break; - case Table.InterfaceImpl: - size = GetTableIndexSize(Table.TypeDef) // Class - + GetCodedIndexSize(CodedIndex.TypeDefOrRef); // Interface - break; - case Table.MemberRef: - size = GetCodedIndexSize(CodedIndex.MemberRefParent) // Class - + stridx_size // Name - + blobidx_size; // Signature - break; - case Table.Constant: - size = 2 // Type - + GetCodedIndexSize(CodedIndex.HasConstant) // Parent - + blobidx_size; // Value - break; - case Table.CustomAttribute: - size = GetCodedIndexSize(CodedIndex.HasCustomAttribute) // Parent - + GetCodedIndexSize(CodedIndex.CustomAttributeType) // Type - + blobidx_size; // Value - break; - case Table.FieldMarshal: - size = GetCodedIndexSize(CodedIndex.HasFieldMarshal) // Parent - + blobidx_size; // NativeType - break; - case Table.DeclSecurity: - size = 2 // Action - + GetCodedIndexSize(CodedIndex.HasDeclSecurity) // Parent - + blobidx_size; // PermissionSet - break; - case Table.ClassLayout: - size = 6 // PackingSize 2, ClassSize 4 - + GetTableIndexSize(Table.TypeDef); // Parent - break; - case Table.FieldLayout: - size = 4 // Offset - + GetTableIndexSize(Table.Field); // Field - break; - case Table.StandAloneSig: - size = blobidx_size; // Signature - break; - case Table.EventMap: - size = GetTableIndexSize(Table.TypeDef) // Parent - + GetTableIndexSize(Table.Event); // EventList - break; - case Table.EventPtr: - size = GetTableIndexSize(Table.Event); // Event - break; - case Table.Event: - size = 2 // Flags - + stridx_size // Name - + GetCodedIndexSize(CodedIndex.TypeDefOrRef); // EventType - break; - case Table.PropertyMap: - size = GetTableIndexSize(Table.TypeDef) // Parent - + GetTableIndexSize(Table.Property); // PropertyList - break; - case Table.PropertyPtr: - size = GetTableIndexSize(Table.Property); // Property - break; - case Table.Property: - size = 2 // Flags - + stridx_size // Name - + blobidx_size; // Type - break; - case Table.MethodSemantics: - size = 2 // Semantics - + GetTableIndexSize(Table.Method) // Method - + GetCodedIndexSize(CodedIndex.HasSemantics); // Association - break; - case Table.MethodImpl: - size = GetTableIndexSize(Table.TypeDef) // Class - + GetCodedIndexSize(CodedIndex.MethodDefOrRef) // MethodBody - + GetCodedIndexSize(CodedIndex.MethodDefOrRef); // MethodDeclaration - break; - case Table.ModuleRef: - size = stridx_size; // Name - break; - case Table.TypeSpec: - size = blobidx_size; // Signature - break; - case Table.ImplMap: - size = 2 // MappingFlags - + GetCodedIndexSize(CodedIndex.MemberForwarded) // MemberForwarded - + stridx_size // ImportName - + GetTableIndexSize(Table.ModuleRef); // ImportScope - break; - case Table.FieldRVA: - size = 4 // RVA - + GetTableIndexSize(Table.Field); // Field - break; - case Table.EncLog: - case Table.EncMap: - size = 4; - break; - case Table.Assembly: - size = 16 // HashAlgId 4, Version 4 * 2, Flags 4 - + blobidx_size // PublicKey - + (stridx_size * 2); // Name, Culture - break; - case Table.AssemblyProcessor: - size = 4; // Processor - break; - case Table.AssemblyOS: - size = 12; // Platform 4, Version 2 * 4 - break; - case Table.AssemblyRef: - size = 12 // Version 2 * 4 + Flags 4 - + (blobidx_size * 2) // PublicKeyOrToken, HashValue - + (stridx_size * 2); // Name, Culture - break; - case Table.AssemblyRefProcessor: - size = 4 // Processor - + GetTableIndexSize(Table.AssemblyRef); // AssemblyRef - break; - case Table.AssemblyRefOS: - size = 12 // Platform 4, Version 2 * 4 - + GetTableIndexSize(Table.AssemblyRef); // AssemblyRef - break; - case Table.File: - size = 4 // Flags - + stridx_size // Name - + blobidx_size; // HashValue - break; - case Table.ExportedType: - size = 8 // Flags 4, TypeDefId 4 - + (stridx_size * 2) // Name, Namespace - + GetCodedIndexSize(CodedIndex.Implementation); // Implementation - break; - case Table.ManifestResource: - size = 8 // Offset, Flags - + stridx_size // Name - + GetCodedIndexSize(CodedIndex.Implementation); // Implementation - break; - case Table.NestedClass: - size = GetTableIndexSize(Table.TypeDef) // NestedClass - + GetTableIndexSize(Table.TypeDef); // EnclosingClass - break; - case Table.GenericParam: - size = 4 // Number, Flags - + GetCodedIndexSize(CodedIndex.TypeOrMethodDef) // Owner - + stridx_size; // Name - break; - case Table.MethodSpec: - size = GetCodedIndexSize(CodedIndex.MethodDefOrRef) // Method - + blobidx_size; // Instantiation - break; - case Table.GenericParamConstraint: - size = GetTableIndexSize(Table.GenericParam) // Owner - + GetCodedIndexSize(CodedIndex.TypeDefOrRef); // Constraint - break; - default: - throw new NotSupportedException(); - } - - tables[i].RowSize = (uint)size; - tables[i].Offset = offset; - - offset += (uint)size * tables[i].Length; - } - } - - public static Image ReadImageFrom(Stream stream) - { - try - { - var reader = new ImageReader(stream); - reader.ReadImage(); - return reader.image; - } - catch (EndOfStreamException e) - { - throw new BadImageFormatException(Mixin.GetFullyQualifiedName(stream), e); - } - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageWriter.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageWriter.cs deleted file mode 100644 index e69de29b..00000000 diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Section.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Section.cs deleted file mode 100644 index 6a4c7bab..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Section.cs +++ /dev/null @@ -1,43 +0,0 @@ -// -// Section.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using RVA = System.UInt32; - -namespace Mono.Cecil.PE { - - sealed class Section { - public string Name; - public RVA VirtualAddress; - public uint VirtualSize; - public uint SizeOfRawData; - public uint PointerToRawData; - public byte [] Data; - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/TextMap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/TextMap.cs deleted file mode 100644 index e69de29b..00000000 diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyDefinition.cs deleted file mode 100644 index 4ae62ee4..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyDefinition.cs +++ /dev/null @@ -1,163 +0,0 @@ -// -// AssemblyDefinition.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -using Mono.Collections.Generic; - -namespace Mono.Cecil -{ - - public sealed class AssemblyDefinition : ICustomAttributeProvider, ISecurityDeclarationProvider - { - - AssemblyNameDefinition name; - - internal ModuleDefinition main_module; - Collection modules; - Collection custom_attributes; - Collection security_declarations; - - public AssemblyNameDefinition Name - { - get { return name; } - set { name = value; } - } - - public string FullName - { - get { return name != null ? name.FullName : string.Empty; } - } - - public MetadataToken MetadataToken - { - get { return new MetadataToken(TokenType.Assembly, 1); } - set { } - } - - public Collection Modules - { - get - { - if (modules != null) - return modules; - - if (main_module.HasImage) - return main_module.Read(ref modules, this, (_, reader) => reader.ReadModules()); - - return modules = new Collection(1) { main_module }; - } - } - - public ModuleDefinition MainModule - { - get { return main_module; } - } - - public MethodDefinition EntryPoint - { - get { return main_module.EntryPoint; } - set { main_module.EntryPoint = value; } - } - - public bool HasCustomAttributes - { - get - { - if (custom_attributes != null) - return custom_attributes.Count > 0; - - return Mixin.GetHasCustomAttributes(this, main_module); - } - } - - public Collection CustomAttributes - { - get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, main_module)); } - } - - public bool HasSecurityDeclarations - { - get - { - if (security_declarations != null) - return security_declarations.Count > 0; - - return Mixin.GetHasSecurityDeclarations(this, main_module); - } - } - - public Collection SecurityDeclarations - { - get { return security_declarations ?? (Mixin.GetSecurityDeclarations(this, ref security_declarations, main_module)); } - } - - internal AssemblyDefinition() - { - } - - - - public static AssemblyDefinition ReadAssembly(string fileName) - { - return ReadAssembly(ModuleDefinition.ReadModule(fileName)); - } - - public static AssemblyDefinition ReadAssembly(string fileName, ReaderParameters parameters) - { - return ReadAssembly(ModuleDefinition.ReadModule(fileName, parameters)); - } - - public static AssemblyDefinition ReadAssembly(Stream stream) - { - return ReadAssembly(ModuleDefinition.ReadModule(stream)); - } - - public static AssemblyDefinition ReadAssembly(Stream stream, ReaderParameters parameters) - { - return ReadAssembly(ModuleDefinition.ReadModule(stream, parameters)); - } - - static AssemblyDefinition ReadAssembly(ModuleDefinition module) - { - var assembly = module.Assembly; - if (assembly == null) - throw new ArgumentException(); - - return assembly; - } - - - - public override string ToString() - { - return this.FullName; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyFlags.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyFlags.cs deleted file mode 100644 index 72a0eb06..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyFlags.cs +++ /dev/null @@ -1,42 +0,0 @@ -// -// AssemblyFlags.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - [Flags] - public enum AssemblyAttributes : uint { - PublicKey = 0x0001, - SideBySideCompatible = 0x0000, - Retargetable = 0x0100, - WindowsRuntime = 0x0200, - DisableJITCompileOptimizer = 0x4000, - EnableJITCompileTracking = 0x8000, - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyHashAlgorithm.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyHashAlgorithm.cs deleted file mode 100644 index 79a5699d..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyHashAlgorithm.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// AssemblyHashAlgorithm.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public enum AssemblyHashAlgorithm : uint { - None = 0x0000, - Reserved = 0x8003, // MD5 - SHA1 = 0x8004 - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyLinkedResource.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyLinkedResource.cs deleted file mode 100644 index 4d8bac0b..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyLinkedResource.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// AssemblyLinkedResource.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - public sealed class AssemblyLinkedResource : Resource { - - AssemblyNameReference reference; - - public AssemblyNameReference Assembly { - get { return reference; } - set { reference = value; } - } - - public override ResourceType ResourceType { - get { return ResourceType.AssemblyLinked; } - } - - public AssemblyLinkedResource (string name, ManifestResourceAttributes flags) - : base (name, flags) - { - } - - public AssemblyLinkedResource (string name, ManifestResourceAttributes flags, AssemblyNameReference reference) - : base (name, flags) - { - this.reference = reference; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameDefinition.cs deleted file mode 100644 index dc6b9057..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameDefinition.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -// AssemblyNameDefinition.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - public sealed class AssemblyNameDefinition : AssemblyNameReference { - - public override byte [] Hash { - get { return Empty.Array; } - } - - internal AssemblyNameDefinition () - { - this.token = new MetadataToken (TokenType.Assembly, 1); - } - - public AssemblyNameDefinition (string name, Version version) - : base (name, version) - { - this.token = new MetadataToken (TokenType.Assembly, 1); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameReference.cs deleted file mode 100644 index da77d504..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameReference.cs +++ /dev/null @@ -1,296 +0,0 @@ -// -// AssemblyNameReference.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Globalization; -using System.Security.Cryptography; -using System.Text; - -namespace Mono.Cecil -{ - - public class AssemblyNameReference : IMetadataScope - { - - string name; - string culture; - Version version; - uint attributes; - byte[] public_key; - byte[] public_key_token; - AssemblyHashAlgorithm hash_algorithm; - byte[] hash; - - internal MetadataToken token; - - string full_name; - - public string Name - { - get { return name; } - set - { - name = value; - full_name = null; - } - } - - public string Culture - { - get { return culture; } - set - { - culture = value; - full_name = null; - } - } - - public Version Version - { - get { return version; } - set - { - version = value; - full_name = null; - } - } - - public AssemblyAttributes Attributes - { - get { return (AssemblyAttributes)attributes; } - set { attributes = (uint)value; } - } - - public bool HasPublicKey - { - get { return Mixin.GetAttributes(attributes,(uint)AssemblyAttributes.PublicKey); } - set { attributes =Mixin.SetAttributes(attributes,(uint)AssemblyAttributes.PublicKey, value); } - } - - public bool IsSideBySideCompatible - { - get { return Mixin.GetAttributes(attributes,(uint)AssemblyAttributes.SideBySideCompatible); } - set { attributes =Mixin.SetAttributes(attributes,(uint)AssemblyAttributes.SideBySideCompatible, value); } - } - - public bool IsRetargetable - { - get { return Mixin.GetAttributes(attributes,(uint)AssemblyAttributes.Retargetable); } - set { attributes =Mixin.SetAttributes(attributes,(uint)AssemblyAttributes.Retargetable, value); } - } - - public bool IsWindowsRuntime - { - get { return Mixin.GetAttributes(attributes,(uint)AssemblyAttributes.WindowsRuntime); } - set { attributes =Mixin.SetAttributes(attributes,(uint)AssemblyAttributes.WindowsRuntime, value); } - } - - public byte[] PublicKey - { - get { return public_key ?? Empty.Array; } - set - { - public_key = value; - HasPublicKey = !Mixin.IsNullOrEmpty(public_key); - public_key_token = Empty.Array; - full_name = null; - } - } - - public byte[] PublicKeyToken - { - get - { - if (Mixin.IsNullOrEmpty(public_key_token) && !Mixin.IsNullOrEmpty(public_key)) - { - var hash = HashPublicKey(); - // we need the last 8 bytes in reverse order - byte[] local_public_key_token = new byte[8]; - Array.Copy(hash, (hash.Length - 8), local_public_key_token, 0, 8); - Array.Reverse(local_public_key_token, 0, 8); - public_key_token = local_public_key_token; // publish only once finished (required for thread-safety) - } - return public_key_token ?? Empty.Array; - } - set - { - public_key_token = value; - full_name = null; - } - } - - byte[] HashPublicKey() - { - HashAlgorithm algorithm; - - switch (hash_algorithm) - { - case AssemblyHashAlgorithm.Reserved: - - throw new NotSupportedException(); - - default: - // None default to SHA1 - algorithm = new SHA1Managed(); - break; - - } - - using (algorithm) - return algorithm.ComputeHash(public_key); - } - - public virtual MetadataScopeType MetadataScopeType - { - get { return MetadataScopeType.AssemblyNameReference; } - } - - public string FullName - { - get - { - if (full_name != null) - return full_name; - - const string sep = ", "; - - var builder = new StringBuilder(); - builder.Append(name); - if (version != null) - { - builder.Append(sep); - builder.Append("Version="); - builder.Append(version.ToString()); - } - builder.Append(sep); - builder.Append("Culture="); - builder.Append(string.IsNullOrEmpty(culture) ? "neutral" : culture); - builder.Append(sep); - builder.Append("PublicKeyToken="); - - var pk_token = PublicKeyToken; - if (!Mixin.IsNullOrEmpty(pk_token) && pk_token.Length > 0) - { - for (int i = 0; i < pk_token.Length; i++) - { - builder.Append(pk_token[i].ToString("x2")); - } - } - else - builder.Append("null"); - - return full_name = builder.ToString(); - } - } - - public static AssemblyNameReference Parse(string fullName) - { - if (fullName == null) - throw new ArgumentNullException("fullName"); - if (fullName.Length == 0) - throw new ArgumentException("Name can not be empty"); - - var name = new AssemblyNameReference(); - var tokens = fullName.Split(','); - for (int i = 0; i < tokens.Length; i++) - { - var token = tokens[i].Trim(); - - if (i == 0) - { - name.Name = token; - continue; - } - - var parts = token.Split('='); - if (parts.Length != 2) - throw new ArgumentException("Malformed name"); - - switch (parts[0].ToLowerInvariant()) - { - case "version": - name.Version = new Version(parts[1]); - break; - case "culture": - name.Culture = parts[1]; - break; - case "publickeytoken": - var pk_token = parts[1]; - if (pk_token == "null") - break; - - name.PublicKeyToken = new byte[pk_token.Length / 2]; - for (int j = 0; j < name.PublicKeyToken.Length; j++) - name.PublicKeyToken[j] = Byte.Parse(pk_token.Substring(j * 2, 2), NumberStyles.HexNumber); - - break; - } - } - - return name; - } - - public AssemblyHashAlgorithm HashAlgorithm - { - get { return hash_algorithm; } - set { hash_algorithm = value; } - } - - public virtual byte[] Hash - { - get { return hash; } - set { hash = value; } - } - - public MetadataToken MetadataToken - { - get { return token; } - set { token = value; } - } - - internal AssemblyNameReference() - { - } - - public AssemblyNameReference(string name, Version version) - { - if (name == null) - throw new ArgumentNullException("name"); - - this.name = name; - this.version = version; - this.hash_algorithm = AssemblyHashAlgorithm.None; - this.token = new MetadataToken(TokenType.AssemblyRef); - } - - public override string ToString() - { - return this.FullName; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyReader.cs deleted file mode 100644 index 72a43de3..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyReader.cs +++ /dev/null @@ -1,3342 +0,0 @@ -// -// AssemblyReader.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -using Mono.Collections.Generic; -using Mono.Cecil.Cil; -using Mono.Cecil.Metadata; -using Mono.Cecil.PE; - -using RVA = System.UInt32; - -namespace Mono.Cecil -{ - - abstract class ModuleReader - { - - readonly protected Image image; - readonly protected ModuleDefinition module; - - protected ModuleReader(Image image, ReadingMode mode) - { - this.image = image; - this.module = new ModuleDefinition(image); - this.module.ReadingMode = mode; - } - - protected abstract void ReadModule(); - - protected void ReadModuleManifest(MetadataReader reader) - { - reader.Populate(module); - - ReadAssembly(reader); - } - - void ReadAssembly(MetadataReader reader) - { - var name = reader.ReadAssemblyNameDefinition(); - if (name == null) - { - module.kind = ModuleKind.NetModule; - return; - } - - var assembly = new AssemblyDefinition(); - assembly.Name = name; - - module.assembly = assembly; - assembly.main_module = module; - } - - public static ModuleDefinition CreateModuleFrom(Image image, ReaderParameters parameters) - { - var module = ReadModule(image, parameters); - - ReadSymbols(module, parameters); - - if (parameters.AssemblyResolver != null) - module.assembly_resolver = parameters.AssemblyResolver; - - if (parameters.MetadataResolver != null) - module.metadata_resolver = parameters.MetadataResolver; - - return module; - } - - static void ReadSymbols(ModuleDefinition module, ReaderParameters parameters) - { - var symbol_reader_provider = parameters.SymbolReaderProvider; - - if (symbol_reader_provider == null && parameters.ReadSymbols) - symbol_reader_provider = SymbolProvider.GetPlatformReaderProvider(); - - if (symbol_reader_provider != null) - { - module.SymbolReaderProvider = symbol_reader_provider; - - var reader = parameters.SymbolStream != null - ? symbol_reader_provider.GetSymbolReader(module, parameters.SymbolStream) - : symbol_reader_provider.GetSymbolReader(module, module.FullyQualifiedName); - - module.ReadSymbols(reader); - } - } - - static ModuleDefinition ReadModule(Image image, ReaderParameters parameters) - { - var reader = CreateModuleReader(image, parameters.ReadingMode); - reader.ReadModule(); - return reader.module; - } - - static ModuleReader CreateModuleReader(Image image, ReadingMode mode) - { - switch (mode) - { - case ReadingMode.Immediate: - return new ImmediateModuleReader(image); - case ReadingMode.Deferred: - return new DeferredModuleReader(image); - default: - throw new ArgumentException(); - } - } - } - - sealed class ImmediateModuleReader : ModuleReader - { - - public ImmediateModuleReader(Image image) - : base(image, ReadingMode.Immediate) - { - } - - protected override void ReadModule() - { - this.module.Read(this.module, (module, reader) => - { - ReadModuleManifest(reader); - ReadModule(module); - return module; - }); - } - - public static void ReadModule(ModuleDefinition module) - { - if (module.HasAssemblyReferences) - Read(module.AssemblyReferences); - if (module.HasResources) - Read(module.Resources); - if (module.HasModuleReferences) - Read(module.ModuleReferences); - if (module.HasTypes) - ReadTypes(module.Types); - if (module.HasExportedTypes) - Read(module.ExportedTypes); - if (module.HasCustomAttributes) - Read(module.CustomAttributes); - - var assembly = module.Assembly; - if (assembly == null) - return; - - if (assembly.HasCustomAttributes) - Read(assembly.CustomAttributes); - if (assembly.HasSecurityDeclarations) - Read(assembly.SecurityDeclarations); - } - - static void ReadTypes(Collection types) - { - for (int i = 0; i < types.Count; i++) - ReadType(types[i]); - } - - static void ReadType(TypeDefinition type) - { - ReadGenericParameters(type); - - if (type.HasInterfaces) - Read(type.Interfaces); - - if (type.HasNestedTypes) - ReadTypes(type.NestedTypes); - - if (type.HasLayoutInfo) - Read(type.ClassSize); - - if (type.HasFields) - ReadFields(type); - - if (type.HasMethods) - ReadMethods(type); - - if (type.HasProperties) - ReadProperties(type); - - if (type.HasEvents) - ReadEvents(type); - - ReadSecurityDeclarations(type); - ReadCustomAttributes(type); - } - - static void ReadGenericParameters(IGenericParameterProvider provider) - { - if (!provider.HasGenericParameters) - return; - - var parameters = provider.GenericParameters; - - for (int i = 0; i < parameters.Count; i++) - { - var parameter = parameters[i]; - - if (parameter.HasConstraints) - Read(parameter.Constraints); - - if (parameter.HasCustomAttributes) - Read(parameter.CustomAttributes); - } - } - - static void ReadSecurityDeclarations(ISecurityDeclarationProvider provider) - { - if (provider.HasSecurityDeclarations) - Read(provider.SecurityDeclarations); - } - - static void ReadCustomAttributes(ICustomAttributeProvider provider) - { - if (provider.HasCustomAttributes) - Read(provider.CustomAttributes); - } - - static void ReadFields(TypeDefinition type) - { - var fields = type.Fields; - - for (int i = 0; i < fields.Count; i++) - { - var field = fields[i]; - - if (field.HasConstant) - Read(field.Constant); - - if (field.HasLayoutInfo) - Read(field.Offset); - - if (field.RVA > 0) - Read(field.InitialValue); - - if (field.HasMarshalInfo) - Read(field.MarshalInfo); - - ReadCustomAttributes(field); - } - } - - static void ReadMethods(TypeDefinition type) - { - var methods = type.Methods; - - for (int i = 0; i < methods.Count; i++) - { - var method = methods[i]; - - ReadGenericParameters(method); - - if (method.HasParameters) - ReadParameters(method); - - if (method.HasOverrides) - Read(method.Overrides); - - if (method.IsPInvokeImpl) - Read(method.PInvokeInfo); - - ReadSecurityDeclarations(method); - ReadCustomAttributes(method); - - var return_type = method.MethodReturnType; - if (return_type.HasConstant) - Read(return_type.Constant); - - if (return_type.HasMarshalInfo) - Read(return_type.MarshalInfo); - - ReadCustomAttributes(return_type); - } - } - - static void ReadParameters(MethodDefinition method) - { - var parameters = method.Parameters; - - for (int i = 0; i < parameters.Count; i++) - { - var parameter = parameters[i]; - - if (parameter.HasConstant) - Read(parameter.Constant); - - if (parameter.HasMarshalInfo) - Read(parameter.MarshalInfo); - - ReadCustomAttributes(parameter); - } - } - - static void ReadProperties(TypeDefinition type) - { - var properties = type.Properties; - - for (int i = 0; i < properties.Count; i++) - { - var property = properties[i]; - - Read(property.GetMethod); - - if (property.HasConstant) - Read(property.Constant); - - ReadCustomAttributes(property); - } - } - - static void ReadEvents(TypeDefinition type) - { - var events = type.Events; - - for (int i = 0; i < events.Count; i++) - { - var @event = events[i]; - - Read(@event.AddMethod); - - ReadCustomAttributes(@event); - } - } - - static void Read(object collection) - { - } - } - - sealed class DeferredModuleReader : ModuleReader - { - - public DeferredModuleReader(Image image) - : base(image, ReadingMode.Deferred) - { - } - - protected override void ReadModule() - { - this.module.Read(this.module, (module, reader) => - { - ReadModuleManifest(reader); - return module; - }); - } - } - - sealed class MetadataReader : ByteBuffer - { - - readonly internal Image image; - readonly internal ModuleDefinition module; - readonly internal MetadataSystem metadata; - - internal IGenericContext context; - internal CodeReader code; - - uint Position - { - get { return (uint)base.position; } - set { base.position = (int)value; } - } - - public MetadataReader(ModuleDefinition module) - : base(module.Image.MetadataSection.Data) - { - this.image = module.Image; - this.module = module; - this.metadata = module.MetadataSystem; - this.code = new CodeReader(image.MetadataSection, this); - } - - int GetCodedIndexSize(CodedIndex index) - { - return image.GetCodedIndexSize(index); - } - - uint ReadByIndexSize(int size) - { - if (size == 4) - return ReadUInt32(); - else - return ReadUInt16(); - } - - byte[] ReadBlob() - { - var blob_heap = image.BlobHeap; - if (blob_heap == null) - { - position += 2; - return Empty.Array; - } - - return blob_heap.Read(ReadBlobIndex()); - } - - byte[] ReadBlob(uint signature) - { - var blob_heap = image.BlobHeap; - if (blob_heap == null) - return Empty.Array; - - return blob_heap.Read(signature); - } - - uint ReadBlobIndex() - { - var blob_heap = image.BlobHeap; - return ReadByIndexSize(blob_heap != null ? blob_heap.IndexSize : 2); - } - - string ReadString() - { - return image.StringHeap.Read(ReadByIndexSize(image.StringHeap.IndexSize)); - } - - uint ReadStringIndex() - { - return ReadByIndexSize(image.StringHeap.IndexSize); - } - - uint ReadTableIndex(Table table) - { - return ReadByIndexSize(image.GetTableIndexSize(table)); - } - - MetadataToken ReadMetadataToken(CodedIndex index) - { - return Mixin.GetMetadataToken(index, ReadByIndexSize(GetCodedIndexSize(index))); - } - - int MoveTo(Table table) - { - var info = image.TableHeap[table]; - if (info.Length != 0) - Position = info.Offset; - - return (int)info.Length; - } - - bool MoveTo(Table table, uint row) - { - var info = image.TableHeap[table]; - var length = info.Length; - if (length == 0 || row > length) - return false; - - Position = info.Offset + (info.RowSize * (row - 1)); - return true; - } - - public AssemblyNameDefinition ReadAssemblyNameDefinition() - { - if (MoveTo(Table.Assembly) == 0) - return null; - - var name = new AssemblyNameDefinition(); - - name.HashAlgorithm = (AssemblyHashAlgorithm)ReadUInt32(); - - PopulateVersionAndFlags(name); - - name.PublicKey = ReadBlob(); - - PopulateNameAndCulture(name); - - return name; - } - - public ModuleDefinition Populate(ModuleDefinition module) - { - if (MoveTo(Table.Module) == 0) - return module; - - Advance(2); // Generation - - module.Name = ReadString(); - module.Mvid = image.GuidHeap.Read(ReadByIndexSize(image.GuidHeap.IndexSize)); - - return module; - } - - void InitializeAssemblyReferences() - { - if (metadata.AssemblyReferences != null) - return; - - int length = MoveTo(Table.AssemblyRef); - var references = metadata.AssemblyReferences = new AssemblyNameReference[length]; - - for (uint i = 0; i < length; i++) - { - var reference = new AssemblyNameReference(); - reference.token = new MetadataToken(TokenType.AssemblyRef, i + 1); - - PopulateVersionAndFlags(reference); - - var key_or_token = ReadBlob(); - - if (reference.HasPublicKey) - reference.PublicKey = key_or_token; - else - reference.PublicKeyToken = key_or_token; - - PopulateNameAndCulture(reference); - - reference.Hash = ReadBlob(); - - references[i] = reference; - } - } - - public Collection ReadAssemblyReferences() - { - InitializeAssemblyReferences(); - - return new Collection(metadata.AssemblyReferences); - } - - public MethodDefinition ReadEntryPoint() - { - if (module.Image.EntryPointToken == 0) - return null; - - var token = new MetadataToken(module.Image.EntryPointToken); - return GetMethodDefinition(token.RID); - } - - public Collection ReadModules() - { - var modules = new Collection(1); - modules.Add(this.module); - - int length = MoveTo(Table.File); - for (uint i = 1; i <= length; i++) - { - var attributes = (FileAttributes)ReadUInt32(); - var name = ReadString(); - ReadBlobIndex(); - - if (attributes != FileAttributes.ContainsMetaData) - continue; - - var parameters = new ReaderParameters - { - ReadingMode = module.ReadingMode, - SymbolReaderProvider = module.SymbolReaderProvider, - }; - - modules.Add(ModuleDefinition.ReadModule( - GetModuleFileName(name), parameters)); - } - - return modules; - } - - string GetModuleFileName(string name) - { - if (module.FullyQualifiedName == null) - throw new NotSupportedException(); - - var path = Path.GetDirectoryName(module.FullyQualifiedName); - return Path.Combine(path, name); - } - - void InitializeModuleReferences() - { - if (metadata.ModuleReferences != null) - return; - - int length = MoveTo(Table.ModuleRef); - var references = metadata.ModuleReferences = new ModuleReference[length]; - - for (uint i = 0; i < length; i++) - { - var reference = new ModuleReference(ReadString()); - reference.token = new MetadataToken(TokenType.ModuleRef, i + 1); - - references[i] = reference; - } - } - - public Collection ReadModuleReferences() - { - InitializeModuleReferences(); - - return new Collection(metadata.ModuleReferences); - } - - public bool HasFileResource() - { - int length = MoveTo(Table.File); - if (length == 0) - return false; - - for (uint i = 1; i <= length; i++) - if (ReadFileRecord(i).Col1 == FileAttributes.ContainsNoMetaData) - return true; - - return false; - } - - public Collection ReadResources() - { - int length = MoveTo(Table.ManifestResource); - var resources = new Collection(length); - - for (int i = 1; i <= length; i++) - { - var offset = ReadUInt32(); - var flags = (ManifestResourceAttributes)ReadUInt32(); - var name = ReadString(); - var implementation = ReadMetadataToken(CodedIndex.Implementation); - - Resource resource; - - if (implementation.RID == 0) - { - resource = new EmbeddedResource(name, flags, offset, this); - } - else if (implementation.TokenType == TokenType.AssemblyRef) - { - resource = new AssemblyLinkedResource(name, flags) - { - Assembly = (AssemblyNameReference)GetTypeReferenceScope(implementation), - }; - } - else if (implementation.TokenType == TokenType.File) - { - var file_record = ReadFileRecord(implementation.RID); - - resource = new LinkedResource(name, flags) - { - File = file_record.Col2, - hash = ReadBlob(file_record.Col3) - }; - } - else - throw new NotSupportedException(); - - resources.Add(resource); - } - - return resources; - } - - Row ReadFileRecord(uint rid) - { - var position = this.position; - - if (!MoveTo(Table.File, rid)) - throw new ArgumentException(); - - var record = new Row( - (FileAttributes)ReadUInt32(), - ReadString(), - ReadBlobIndex()); - - this.position = position; - - return record; - } - - 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 length = buffer[position] - | (buffer[position + 1] << 8) - | (buffer[position + 2] << 16) - | (buffer[position + 3] << 24); - - return new MemoryStream(buffer, (int)position + 4, length); - } - - void PopulateVersionAndFlags(AssemblyNameReference name) - { - name.Version = new Version( - ReadUInt16(), - ReadUInt16(), - ReadUInt16(), - ReadUInt16()); - - name.Attributes = (AssemblyAttributes)ReadUInt32(); - } - - void PopulateNameAndCulture(AssemblyNameReference name) - { - name.Name = ReadString(); - name.Culture = ReadString(); - } - - public TypeDefinitionCollection ReadTypes() - { - InitializeTypeDefinitions(); - var mtypes = metadata.Types; - var type_count = mtypes.Length - metadata.NestedTypes.Count; - var types = new TypeDefinitionCollection(module, type_count); - - for (int i = 0; i < mtypes.Length; i++) - { - var type = mtypes[i]; - if (IsNested(type.Attributes)) - continue; - - types.Add(type); - } - - if (image.HasTable(Table.MethodPtr) || image.HasTable(Table.FieldPtr)) - CompleteTypes(); - - return types; - } - - void CompleteTypes() - { - var types = metadata.Types; - - for (int i = 0; i < types.Length; i++) - { - var type = types[i]; - - InitializeCollection(type.Fields); - InitializeCollection(type.Methods); - } - } - - void InitializeTypeDefinitions() - { - if (metadata.Types != null) - return; - - InitializeNestedTypes(); - InitializeFields(); - InitializeMethods(); - - int length = MoveTo(Table.TypeDef); - var types = metadata.Types = new TypeDefinition[length]; - - for (uint i = 0; i < length; i++) - { - if (types[i] != null) - continue; - - types[i] = ReadType(i + 1); - } - } - - static bool IsNested(TypeAttributes attributes) - { - switch (attributes & TypeAttributes.VisibilityMask) - { - case TypeAttributes.NestedAssembly: - case TypeAttributes.NestedFamANDAssem: - case TypeAttributes.NestedFamily: - case TypeAttributes.NestedFamORAssem: - case TypeAttributes.NestedPrivate: - case TypeAttributes.NestedPublic: - return true; - default: - return false; - } - } - - public bool HasNestedTypes(TypeDefinition type) - { - uint[] mapping; - InitializeNestedTypes(); - - if (!metadata.TryGetNestedTypeMapping(type, out mapping)) - return false; - - return mapping.Length > 0; - } - - public Collection ReadNestedTypes(TypeDefinition type) - { - InitializeNestedTypes(); - uint[] mapping; - if (!metadata.TryGetNestedTypeMapping(type, out mapping)) - return new MemberDefinitionCollection(type); - - var nested_types = new MemberDefinitionCollection(type, mapping.Length); - - for (int i = 0; i < mapping.Length; i++) - { - var nested_type = GetTypeDefinition(mapping[i]); - - if (nested_type != null) - nested_types.Add(nested_type); - } - - metadata.RemoveNestedTypeMapping(type); - - return nested_types; - } - - void InitializeNestedTypes() - { - if (metadata.NestedTypes != null) - return; - - var length = MoveTo(Table.NestedClass); - - metadata.NestedTypes = new Dictionary(length); - metadata.ReverseNestedTypes = new Dictionary(length); - - if (length == 0) - return; - - for (int i = 1; i <= length; i++) - { - var nested = ReadTableIndex(Table.TypeDef); - var declaring = ReadTableIndex(Table.TypeDef); - - AddNestedMapping(declaring, nested); - } - } - - void AddNestedMapping(uint declaring, uint nested) - { - metadata.SetNestedTypeMapping(declaring, AddMapping(metadata.NestedTypes, declaring, nested)); - metadata.SetReverseNestedTypeMapping(nested, declaring); - } - - static TValue[] AddMapping(Dictionary cache, TKey key, TValue value) - { - TValue[] mapped; - if (!cache.TryGetValue(key, out mapped)) - { - mapped = new[] { value }; - return mapped; - } - - var new_mapped = new TValue[mapped.Length + 1]; - Array.Copy(mapped, new_mapped, mapped.Length); - new_mapped[mapped.Length] = value; - return new_mapped; - } - - TypeDefinition ReadType(uint rid) - { - if (!MoveTo(Table.TypeDef, rid)) - return null; - - var attributes = (TypeAttributes)ReadUInt32(); - var name = ReadString(); - var @namespace = ReadString(); - var type = new TypeDefinition(@namespace, name, attributes); - type.token = new MetadataToken(TokenType.TypeDef, rid); - type.scope = module; - type.module = module; - - metadata.AddTypeDefinition(type); - - this.context = type; - - type.BaseType = GetTypeDefOrRef(ReadMetadataToken(CodedIndex.TypeDefOrRef)); - - type.fields_range = ReadFieldsRange(rid); - type.methods_range = ReadMethodsRange(rid); - - if (IsNested(attributes)) - type.DeclaringType = GetNestedTypeDeclaringType(type); - - return type; - } - - TypeDefinition GetNestedTypeDeclaringType(TypeDefinition type) - { - uint declaring_rid; - if (!metadata.TryGetReverseNestedTypeMapping(type, out declaring_rid)) - return null; - - metadata.RemoveReverseNestedTypeMapping(type); - return GetTypeDefinition(declaring_rid); - } - - Range ReadFieldsRange(uint type_index) - { - return ReadListRange(type_index, Table.TypeDef, Table.Field); - } - - Range ReadMethodsRange(uint type_index) - { - return ReadListRange(type_index, Table.TypeDef, Table.Method); - } - - Range ReadListRange(uint current_index, Table current, Table target) - { - var list = new Range(); - - list.Start = ReadTableIndex(target); - - uint next_index; - var current_table = image.TableHeap[current]; - - if (current_index == current_table.Length) - next_index = image.TableHeap[target].Length + 1; - else - { - var position = Position; - Position += (uint)(current_table.RowSize - image.GetTableIndexSize(target)); - next_index = ReadTableIndex(target); - Position = position; - } - - list.Length = next_index - list.Start; - - return list; - } - - public Row ReadTypeLayout(TypeDefinition type) - { - InitializeTypeLayouts(); - Row class_layout; - var rid = type.token.RID; - if (!metadata.ClassLayouts.TryGetValue(rid, out class_layout)) - return new Row(Mixin.NoDataMarker, Mixin.NoDataMarker); - - type.PackingSize = (short)class_layout.Col1; - type.ClassSize = (int)class_layout.Col2; - - metadata.ClassLayouts.Remove(rid); - - return new Row((short)class_layout.Col1, (int)class_layout.Col2); - } - - void InitializeTypeLayouts() - { - if (metadata.ClassLayouts != null) - return; - - int length = MoveTo(Table.ClassLayout); - - var class_layouts = metadata.ClassLayouts = new Dictionary>(length); - - for (uint i = 0; i < length; i++) - { - var packing_size = ReadUInt16(); - var class_size = ReadUInt32(); - - var parent = ReadTableIndex(Table.TypeDef); - - class_layouts.Add(parent, new Row(packing_size, class_size)); - } - } - - public TypeReference GetTypeDefOrRef(MetadataToken token) - { - return (TypeReference)LookupToken(token); - } - - public TypeDefinition GetTypeDefinition(uint rid) - { - InitializeTypeDefinitions(); - - var type = metadata.GetTypeDefinition(rid); - if (type != null) - return type; - - return ReadTypeDefinition(rid); - } - - TypeDefinition ReadTypeDefinition(uint rid) - { - if (!MoveTo(Table.TypeDef, rid)) - return null; - - return ReadType(rid); - } - - void InitializeTypeReferences() - { - if (metadata.TypeReferences != null) - return; - - metadata.TypeReferences = new TypeReference[image.GetTableLength(Table.TypeRef)]; - } - - public TypeReference GetTypeReference(string scope, string full_name) - { - InitializeTypeReferences(); - - var length = metadata.TypeReferences.Length; - - for (uint i = 1; i <= length; i++) - { - var type = GetTypeReference(i); - - if (type.FullName != full_name) - continue; - - if (string.IsNullOrEmpty(scope)) - return type; - - if (type.Scope.Name == scope) - return type; - } - - return null; - } - - TypeReference GetTypeReference(uint rid) - { - InitializeTypeReferences(); - - var type = metadata.GetTypeReference(rid); - if (type != null) - return type; - - return ReadTypeReference(rid); - } - - TypeReference ReadTypeReference(uint rid) - { - if (!MoveTo(Table.TypeRef, rid)) - return null; - - TypeReference declaring_type = null; - IMetadataScope scope; - - var scope_token = ReadMetadataToken(CodedIndex.ResolutionScope); - - var name = ReadString(); - var @namespace = ReadString(); - - var type = new TypeReference( - @namespace, - name, - module, - null); - - type.token = new MetadataToken(TokenType.TypeRef, rid); - - metadata.AddTypeReference(type); - - if (scope_token.TokenType == TokenType.TypeRef) - { - declaring_type = GetTypeDefOrRef(scope_token); - - scope = declaring_type != null - ? declaring_type.Scope - : module; - } - else - scope = GetTypeReferenceScope(scope_token); - - type.scope = scope; - type.DeclaringType = declaring_type; - - MetadataSystem.TryProcessPrimitiveTypeReference(type); - - return type; - } - - IMetadataScope GetTypeReferenceScope(MetadataToken scope) - { - switch (scope.TokenType) - { - case TokenType.AssemblyRef: - InitializeAssemblyReferences(); - return metadata.AssemblyReferences[(int)scope.RID - 1]; - case TokenType.ModuleRef: - InitializeModuleReferences(); - return metadata.ModuleReferences[(int)scope.RID - 1]; - case TokenType.Module: - return module; - default: - throw new NotSupportedException(); - } - } - - public IEnumerable GetTypeReferences() - { - InitializeTypeReferences(); - - var length = image.GetTableLength(Table.TypeRef); - - var type_references = new TypeReference[length]; - - for (uint i = 1; i <= length; i++) - type_references[i - 1] = GetTypeReference(i); - - return type_references; - } - - TypeReference GetTypeSpecification(uint rid) - { - if (!MoveTo(Table.TypeSpec, rid)) - return null; - - var reader = ReadSignature(ReadBlobIndex()); - var type = reader.ReadTypeSignature(); - if (type.token.RID == 0) - type.token = new MetadataToken(TokenType.TypeSpec, rid); - - return type; - } - - SignatureReader ReadSignature(uint signature) - { - return new SignatureReader(signature, this); - } - - public bool HasInterfaces(TypeDefinition type) - { - InitializeInterfaces(); - MetadataToken[] mapping; - - return metadata.TryGetInterfaceMapping(type, out mapping); - } - - public Collection ReadInterfaces(TypeDefinition type) - { - InitializeInterfaces(); - MetadataToken[] mapping; - - if (!metadata.TryGetInterfaceMapping(type, out mapping)) - return new Collection(); - - var interfaces = new Collection(mapping.Length); - - this.context = type; - - for (int i = 0; i < mapping.Length; i++) - interfaces.Add(GetTypeDefOrRef(mapping[i])); - - metadata.RemoveInterfaceMapping(type); - - return interfaces; - } - - void InitializeInterfaces() - { - if (metadata.Interfaces != null) - return; - - int length = MoveTo(Table.InterfaceImpl); - - metadata.Interfaces = new Dictionary(length); - - for (int i = 0; i < length; i++) - { - var type = ReadTableIndex(Table.TypeDef); - var @interface = ReadMetadataToken(CodedIndex.TypeDefOrRef); - - AddInterfaceMapping(type, @interface); - } - } - - void AddInterfaceMapping(uint type, MetadataToken @interface) - { - metadata.SetInterfaceMapping(type, AddMapping(metadata.Interfaces, type, @interface)); - } - - public Collection ReadFields(TypeDefinition type) - { - var fields_range = type.fields_range; - if (fields_range.Length == 0) - return new MemberDefinitionCollection(type); - - var fields = new MemberDefinitionCollection(type, (int)fields_range.Length); - this.context = type; - - if (!MoveTo(Table.FieldPtr, fields_range.Start)) - { - if (!MoveTo(Table.Field, fields_range.Start)) - return fields; - - for (uint i = 0; i < fields_range.Length; i++) - ReadField(fields_range.Start + i, fields); - } - else - ReadPointers(Table.FieldPtr, Table.Field, fields_range, fields, ReadField); - - return fields; - } - - void ReadField(uint field_rid, Collection fields) - { - var attributes = (FieldAttributes)ReadUInt16(); - var name = ReadString(); - var signature = ReadBlobIndex(); - - var field = new FieldDefinition(name, attributes, ReadFieldType(signature)); - field.token = new MetadataToken(TokenType.Field, field_rid); - metadata.AddFieldDefinition(field); - - if (IsDeleted(field)) - return; - - fields.Add(field); - } - - void InitializeFields() - { - if (metadata.Fields != null) - return; - - metadata.Fields = new FieldDefinition[image.GetTableLength(Table.Field)]; - } - - TypeReference ReadFieldType(uint signature) - { - var reader = ReadSignature(signature); - - const byte field_sig = 0x6; - - if (reader.ReadByte() != field_sig) - throw new NotSupportedException(); - - return reader.ReadTypeSignature(); - } - - public int ReadFieldRVA(FieldDefinition field) - { - InitializeFieldRVAs(); - var rid = field.token.RID; - - RVA rva; - if (!metadata.FieldRVAs.TryGetValue(rid, out rva)) - return 0; - - var size = GetFieldTypeSize(field.FieldType); - - if (size == 0 || rva == 0) - return 0; - - metadata.FieldRVAs.Remove(rid); - - field.InitialValue = GetFieldInitializeValue(size, rva); - - return (int)rva; - } - - byte[] GetFieldInitializeValue(int size, RVA rva) - { - var section = image.GetSectionAtVirtualAddress(rva); - if (section == null) - return Empty.Array; - - var value = new byte[size]; - Buffer.BlockCopy(section.Data, (int)(rva - section.VirtualAddress), value, 0, size); - return value; - } - - static int GetFieldTypeSize(TypeReference type) - { - int size = 0; - - switch (type.etype) - { - case ElementType.Boolean: - case ElementType.U1: - case ElementType.I1: - size = 1; - break; - case ElementType.U2: - case ElementType.I2: - case ElementType.Char: - size = 2; - break; - case ElementType.U4: - case ElementType.I4: - case ElementType.R4: - size = 4; - break; - case ElementType.U8: - case ElementType.I8: - case ElementType.R8: - size = 8; - break; - case ElementType.Ptr: - case ElementType.FnPtr: - size = IntPtr.Size; - break; - case ElementType.CModOpt: - case ElementType.CModReqD: - return GetFieldTypeSize(((IModifierType)type).ElementType); - default: - var field_type = Mixin.CheckedResolve(type); - if (field_type.HasLayoutInfo) - size = field_type.ClassSize; - - break; - } - - return size; - } - - void InitializeFieldRVAs() - { - if (metadata.FieldRVAs != null) - return; - - int length = MoveTo(Table.FieldRVA); - - var field_rvas = metadata.FieldRVAs = new Dictionary(length); - - for (int i = 0; i < length; i++) - { - var rva = ReadUInt32(); - var field = ReadTableIndex(Table.Field); - - field_rvas.Add(field, rva); - } - } - - public int ReadFieldLayout(FieldDefinition field) - { - InitializeFieldLayouts(); - var rid = field.token.RID; - uint offset; - if (!metadata.FieldLayouts.TryGetValue(rid, out offset)) - return Mixin.NoDataMarker; - - metadata.FieldLayouts.Remove(rid); - - return (int)offset; - } - - void InitializeFieldLayouts() - { - if (metadata.FieldLayouts != null) - return; - - int length = MoveTo(Table.FieldLayout); - - var field_layouts = metadata.FieldLayouts = new Dictionary(length); - - for (int i = 0; i < length; i++) - { - var offset = ReadUInt32(); - var field = ReadTableIndex(Table.Field); - - field_layouts.Add(field, offset); - } - } - - public bool HasEvents(TypeDefinition type) - { - InitializeEvents(); - - Range range; - if (!metadata.TryGetEventsRange(type, out range)) - return false; - - return range.Length > 0; - } - - public Collection ReadEvents(TypeDefinition type) - { - InitializeEvents(); - Range range; - - if (!metadata.TryGetEventsRange(type, out range)) - return new MemberDefinitionCollection(type); - - var events = new MemberDefinitionCollection(type, (int)range.Length); - - metadata.RemoveEventsRange(type); - - if (range.Length == 0) - return events; - - this.context = type; - - if (!MoveTo(Table.EventPtr, range.Start)) - { - if (!MoveTo(Table.Event, range.Start)) - return events; - - for (uint i = 0; i < range.Length; i++) - ReadEvent(range.Start + i, events); - } - else - ReadPointers(Table.EventPtr, Table.Event, range, events, ReadEvent); - - return events; - } - - void ReadEvent(uint event_rid, Collection events) - { - var attributes = (EventAttributes)ReadUInt16(); - var name = ReadString(); - var event_type = GetTypeDefOrRef(ReadMetadataToken(CodedIndex.TypeDefOrRef)); - - var @event = new EventDefinition(name, attributes, event_type); - @event.token = new MetadataToken(TokenType.Event, event_rid); - - if (IsDeleted(@event)) - return; - - events.Add(@event); - } - - void InitializeEvents() - { - if (metadata.Events != null) - return; - - int length = MoveTo(Table.EventMap); - - metadata.Events = new Dictionary(length); - - for (uint i = 1; i <= length; i++) - { - var type_rid = ReadTableIndex(Table.TypeDef); - Range events_range = ReadEventsRange(i); - metadata.AddEventsRange(type_rid, events_range); - } - } - - Range ReadEventsRange(uint rid) - { - return ReadListRange(rid, Table.EventMap, Table.Event); - } - - public bool HasProperties(TypeDefinition type) - { - InitializeProperties(); - - Range range; - if (!metadata.TryGetPropertiesRange(type, out range)) - return false; - - return range.Length > 0; - } - - public Collection ReadProperties(TypeDefinition type) - { - InitializeProperties(); - - Range range; - - if (!metadata.TryGetPropertiesRange(type, out range)) - return new MemberDefinitionCollection(type); - - metadata.RemovePropertiesRange(type); - - var properties = new MemberDefinitionCollection(type, (int)range.Length); - - if (range.Length == 0) - return properties; - - this.context = type; - - if (!MoveTo(Table.PropertyPtr, range.Start)) - { - if (!MoveTo(Table.Property, range.Start)) - return properties; - for (uint i = 0; i < range.Length; i++) - ReadProperty(range.Start + i, properties); - } - else - ReadPointers(Table.PropertyPtr, Table.Property, range, properties, ReadProperty); - - return properties; - } - - void ReadProperty(uint property_rid, Collection properties) - { - var attributes = (PropertyAttributes)ReadUInt16(); - var name = ReadString(); - var signature = ReadBlobIndex(); - - var reader = ReadSignature(signature); - const byte property_signature = 0x8; - - var calling_convention = reader.ReadByte(); - - if ((calling_convention & property_signature) == 0) - throw new NotSupportedException(); - - var has_this = (calling_convention & 0x20) != 0; - - reader.ReadCompressedUInt32(); // count - - var property = new PropertyDefinition(name, attributes, reader.ReadTypeSignature()); - property.HasThis = has_this; - property.token = new MetadataToken(TokenType.Property, property_rid); - - if (IsDeleted(property)) - return; - - properties.Add(property); - } - - void InitializeProperties() - { - if (metadata.Properties != null) - return; - - int length = MoveTo(Table.PropertyMap); - - metadata.Properties = new Dictionary(length); - - for (uint i = 1; i <= length; i++) - { - var type_rid = ReadTableIndex(Table.TypeDef); - var properties_range = ReadPropertiesRange(i); - metadata.AddPropertiesRange(type_rid, properties_range); - } - } - - Range ReadPropertiesRange(uint rid) - { - return ReadListRange(rid, Table.PropertyMap, Table.Property); - } - - MethodSemanticsAttributes ReadMethodSemantics(MethodDefinition method) - { - InitializeMethodSemantics(); - Row row; - if (!metadata.Semantics.TryGetValue(method.token.RID, out row)) - return MethodSemanticsAttributes.None; - - var type = method.DeclaringType; - - switch (row.Col1) - { - case MethodSemanticsAttributes.AddOn: - GetEvent(type, row.Col2).add_method = method; - break; - case MethodSemanticsAttributes.Fire: - GetEvent(type, row.Col2).invoke_method = method; - break; - case MethodSemanticsAttributes.RemoveOn: - GetEvent(type, row.Col2).remove_method = method; - break; - case MethodSemanticsAttributes.Getter: - GetProperty(type, row.Col2).get_method = method; - break; - case MethodSemanticsAttributes.Setter: - GetProperty(type, row.Col2).set_method = method; - break; - case MethodSemanticsAttributes.Other: - switch (row.Col2.TokenType) - { - case TokenType.Event: - { - var @event = GetEvent(type, row.Col2); - if (@event.other_methods == null) - @event.other_methods = new Collection(); - - @event.other_methods.Add(method); - break; - } - case TokenType.Property: - { - var property = GetProperty(type, row.Col2); - if (property.other_methods == null) - property.other_methods = new Collection(); - - property.other_methods.Add(method); - - break; - } - default: - throw new NotSupportedException(); - } - break; - default: - throw new NotSupportedException(); - } - - metadata.Semantics.Remove(method.token.RID); - - return row.Col1; - } - - static EventDefinition GetEvent(TypeDefinition type, MetadataToken token) - { - if (token.TokenType != TokenType.Event) - throw new ArgumentException(); - - return GetMember(type.Events, token); - } - - static PropertyDefinition GetProperty(TypeDefinition type, MetadataToken token) - { - if (token.TokenType != TokenType.Property) - throw new ArgumentException(); - - return GetMember(type.Properties, token); - } - - static TMember GetMember(Collection members, MetadataToken token) where TMember : IMemberDefinition - { - for (int i = 0; i < members.Count; i++) - { - var member = members[i]; - if (member.MetadataToken == token) - return member; - } - - throw new ArgumentException(); - } - - void InitializeMethodSemantics() - { - if (metadata.Semantics != null) - return; - - int length = MoveTo(Table.MethodSemantics); - - var semantics = metadata.Semantics = new Dictionary>(0); - - for (uint i = 0; i < length; i++) - { - var attributes = (MethodSemanticsAttributes)ReadUInt16(); - var method_rid = ReadTableIndex(Table.Method); - var association = ReadMetadataToken(CodedIndex.HasSemantics); - - semantics[method_rid] = new Row(attributes, association); - } - } - - public PropertyDefinition ReadMethods(PropertyDefinition property) - { - ReadAllSemantics(property.DeclaringType); - return property; - } - - public EventDefinition ReadMethods(EventDefinition @event) - { - ReadAllSemantics(@event.DeclaringType); - return @event; - } - - public MethodSemanticsAttributes ReadAllSemantics(MethodDefinition method) - { - ReadAllSemantics(method.DeclaringType); - - return method.SemanticsAttributes; - } - - void ReadAllSemantics(TypeDefinition type) - { - var methods = type.Methods; - for (int i = 0; i < methods.Count; i++) - { - var method = methods[i]; - if (method.sem_attrs_ready) - continue; - - method.sem_attrs = ReadMethodSemantics(method); - method.sem_attrs_ready = true; - } - } - - Range ReadParametersRange(uint method_rid) - { - return ReadListRange(method_rid, Table.Method, Table.Param); - } - - public Collection ReadMethods(TypeDefinition type) - { - var methods_range = type.methods_range; - if (methods_range.Length == 0) - return new MemberDefinitionCollection(type); - - var methods = new MemberDefinitionCollection(type, (int)methods_range.Length); - if (!MoveTo(Table.MethodPtr, methods_range.Start)) - { - if (!MoveTo(Table.Method, methods_range.Start)) - return methods; - - for (uint i = 0; i < methods_range.Length; i++) - ReadMethod(methods_range.Start + i, methods); - } - else - ReadPointers(Table.MethodPtr, Table.Method, methods_range, methods, ReadMethod); - - return methods; - } - - void ReadPointers(Table ptr, Table table, Range range, Collection members, Action> reader) - where TMember : IMemberDefinition - { - for (uint i = 0; i < range.Length; i++) - { - MoveTo(ptr, range.Start + i); - - var rid = ReadTableIndex(table); - MoveTo(table, rid); - - reader(rid, members); - } - } - - static bool IsDeleted(IMemberDefinition member) - { - return member.IsSpecialName && member.Name == "_Deleted"; - } - - void InitializeMethods() - { - if (metadata.Methods != null) - return; - - metadata.Methods = new MethodDefinition[image.GetTableLength(Table.Method)]; - } - - void ReadMethod(uint method_rid, Collection methods) - { - var method = new MethodDefinition(); - method.rva = ReadUInt32(); - method.ImplAttributes = (MethodImplAttributes)ReadUInt16(); - method.Attributes = (MethodAttributes)ReadUInt16(); - method.Name = ReadString(); - method.token = new MetadataToken(TokenType.Method, method_rid); - - if (IsDeleted(method)) - return; - - methods.Add(method); // attach method - - var signature = ReadBlobIndex(); - var param_range = ReadParametersRange(method_rid); - - this.context = method; - - ReadMethodSignature(signature, method); - metadata.AddMethodDefinition(method); - - if (param_range.Length == 0) - return; - - var position = base.position; - ReadParameters(method, param_range); - base.position = position; - } - - void ReadParameters(MethodDefinition method, Range param_range) - { - if (!MoveTo(Table.ParamPtr, param_range.Start)) - { - if (!MoveTo(Table.Param, param_range.Start)) - return; - - for (uint i = 0; i < param_range.Length; i++) - ReadParameter(param_range.Start + i, method); - } - else - ReadParameterPointers(method, param_range); - } - - void ReadParameterPointers(MethodDefinition method, Range range) - { - for (uint i = 0; i < range.Length; i++) - { - MoveTo(Table.ParamPtr, range.Start + i); - - var rid = ReadTableIndex(Table.Param); - - MoveTo(Table.Param, rid); - - ReadParameter(rid, method); - } - } - - void ReadParameter(uint param_rid, MethodDefinition method) - { - var attributes = (ParameterAttributes)ReadUInt16(); - var sequence = ReadUInt16(); - var name = ReadString(); - - var parameter = sequence == 0 - ? method.MethodReturnType.Parameter - : method.Parameters[sequence - 1]; - - parameter.token = new MetadataToken(TokenType.Param, param_rid); - parameter.Name = name; - parameter.Attributes = attributes; - } - - void ReadMethodSignature(uint signature, IMethodSignature method) - { - var reader = ReadSignature(signature); - reader.ReadMethodSignature(method); - } - - public PInvokeInfo ReadPInvokeInfo(MethodDefinition method) - { - InitializePInvokes(); - Row row; - - var rid = method.token.RID; - - if (!metadata.PInvokes.TryGetValue(rid, out row)) - return null; - - metadata.PInvokes.Remove(rid); - - return new PInvokeInfo( - row.Col1, - image.StringHeap.Read(row.Col2), - module.ModuleReferences[(int)row.Col3 - 1]); - } - - void InitializePInvokes() - { - if (metadata.PInvokes != null) - return; - - int length = MoveTo(Table.ImplMap); - - var pinvokes = metadata.PInvokes = new Dictionary>(length); - - for (int i = 1; i <= length; i++) - { - var attributes = (PInvokeAttributes)ReadUInt16(); - var method = ReadMetadataToken(CodedIndex.MemberForwarded); - var name = ReadStringIndex(); - var scope = ReadTableIndex(Table.File); - - if (method.TokenType != TokenType.Method) - continue; - - pinvokes.Add(method.RID, new Row(attributes, name, scope)); - } - } - - public bool HasGenericParameters(IGenericParameterProvider provider) - { - InitializeGenericParameters(); - - Range range; - if (!metadata.TryGetGenericParameterRange(provider, out range)) - return false; - - return range.Length > 0; - } - - public Collection ReadGenericParameters(IGenericParameterProvider provider) - { - InitializeGenericParameters(); - - Range range; - if (!metadata.TryGetGenericParameterRange(provider, out range) - || !MoveTo(Table.GenericParam, range.Start)) - return new GenericParameterCollection(provider); - - metadata.RemoveGenericParameterRange(provider); - - var generic_parameters = new GenericParameterCollection(provider, (int)range.Length); - - for (uint i = 0; i < range.Length; i++) - { - ReadUInt16(); // index - var flags = (GenericParameterAttributes)ReadUInt16(); - ReadMetadataToken(CodedIndex.TypeOrMethodDef); - var name = ReadString(); - - var parameter = new GenericParameter(name, provider); - parameter.token = new MetadataToken(TokenType.GenericParam, range.Start + i); - parameter.Attributes = flags; - - generic_parameters.Add(parameter); - } - - return generic_parameters; - } - - void InitializeGenericParameters() - { - if (metadata.GenericParameters != null) - return; - - metadata.GenericParameters = InitializeRanges( - Table.GenericParam, () => - { - Advance(4); - var next = ReadMetadataToken(CodedIndex.TypeOrMethodDef); - ReadStringIndex(); - return next; - }); - } - - Dictionary InitializeRanges(Table table, Func get_next) - { - int length = MoveTo(table); - var ranges = new Dictionary(length); - - if (length == 0) - return ranges; - - MetadataToken owner = MetadataToken.Zero; - Range range = new Range(1, 0); - - for (uint i = 1; i <= length; i++) - { - var next = get_next(); - - if (i == 1) - { - owner = next; - range.Length++; - } - else if (next != owner) - { - if (owner.RID != 0) - ranges.Add(owner, range); - range = new Range(i, 1); - owner = next; - } - else - range.Length++; - } - - if (owner != MetadataToken.Zero && !ranges.ContainsKey(owner)) - ranges.Add(owner, range); - - return ranges; - } - - public bool HasGenericConstraints(GenericParameter generic_parameter) - { - InitializeGenericConstraints(); - - MetadataToken[] mapping; - if (!metadata.TryGetGenericConstraintMapping(generic_parameter, out mapping)) - return false; - - return mapping.Length > 0; - } - - public Collection ReadGenericConstraints(GenericParameter generic_parameter) - { - InitializeGenericConstraints(); - - MetadataToken[] mapping; - if (!metadata.TryGetGenericConstraintMapping(generic_parameter, out mapping)) - return new Collection(); - - var constraints = new Collection(mapping.Length); - - this.context = (IGenericContext)generic_parameter.Owner; - - for (int i = 0; i < mapping.Length; i++) - constraints.Add(GetTypeDefOrRef(mapping[i])); - - metadata.RemoveGenericConstraintMapping(generic_parameter); - - return constraints; - } - - void InitializeGenericConstraints() - { - if (metadata.GenericConstraints != null) - return; - - var length = MoveTo(Table.GenericParamConstraint); - - metadata.GenericConstraints = new Dictionary(length); - - for (int i = 1; i <= length; i++) - AddGenericConstraintMapping( - ReadTableIndex(Table.GenericParam), - ReadMetadataToken(CodedIndex.TypeDefOrRef)); - } - - void AddGenericConstraintMapping(uint generic_parameter, MetadataToken constraint) - { - metadata.SetGenericConstraintMapping( - generic_parameter, - AddMapping(metadata.GenericConstraints, generic_parameter, constraint)); - } - - public bool HasOverrides(MethodDefinition method) - { - InitializeOverrides(); - MetadataToken[] mapping; - - if (!metadata.TryGetOverrideMapping(method, out mapping)) - return false; - - return mapping.Length > 0; - } - - public Collection ReadOverrides(MethodDefinition method) - { - InitializeOverrides(); - - MetadataToken[] mapping; - if (!metadata.TryGetOverrideMapping(method, out mapping)) - return new Collection(); - - var overrides = new Collection(mapping.Length); - - this.context = method; - - for (int i = 0; i < mapping.Length; i++) - overrides.Add((MethodReference)LookupToken(mapping[i])); - - metadata.RemoveOverrideMapping(method); - - return overrides; - } - - void InitializeOverrides() - { - if (metadata.Overrides != null) - return; - - var length = MoveTo(Table.MethodImpl); - - metadata.Overrides = new Dictionary(length); - - for (int i = 1; i <= length; i++) - { - ReadTableIndex(Table.TypeDef); - - var method = ReadMetadataToken(CodedIndex.MethodDefOrRef); - if (method.TokenType != TokenType.Method) - throw new NotSupportedException(); - - var @override = ReadMetadataToken(CodedIndex.MethodDefOrRef); - - AddOverrideMapping(method.RID, @override); - } - } - - void AddOverrideMapping(uint method_rid, MetadataToken @override) - { - metadata.SetOverrideMapping( - method_rid, - AddMapping(metadata.Overrides, method_rid, @override)); - } - - public MethodBody ReadMethodBody(MethodDefinition method) - { - return code.ReadMethodBody(method); - } - - public CallSite ReadCallSite(MetadataToken token) - { - if (!MoveTo(Table.StandAloneSig, token.RID)) - return null; - - var signature = ReadBlobIndex(); - - var call_site = new CallSite(); - - ReadMethodSignature(signature, call_site); - - call_site.MetadataToken = token; - - return call_site; - } - - public VariableDefinitionCollection ReadVariables(MetadataToken local_var_token) - { - if (!MoveTo(Table.StandAloneSig, local_var_token.RID)) - return null; - - var reader = ReadSignature(ReadBlobIndex()); - const byte local_sig = 0x7; - - if (reader.ReadByte() != local_sig) - throw new NotSupportedException(); - - var count = reader.ReadCompressedUInt32(); - if (count == 0) - return null; - - var variables = new VariableDefinitionCollection((int)count); - - for (int i = 0; i < count; i++) - variables.Add(new VariableDefinition(reader.ReadTypeSignature())); - - return variables; - } - - public IMetadataTokenProvider LookupToken(MetadataToken token) - { - var rid = token.RID; - - if (rid == 0) - return null; - - IMetadataTokenProvider element; - var position = this.position; - var context = this.context; - - switch (token.TokenType) - { - case TokenType.TypeDef: - element = GetTypeDefinition(rid); - break; - case TokenType.TypeRef: - element = GetTypeReference(rid); - break; - case TokenType.TypeSpec: - element = GetTypeSpecification(rid); - break; - case TokenType.Field: - element = GetFieldDefinition(rid); - break; - case TokenType.Method: - element = GetMethodDefinition(rid); - break; - case TokenType.MemberRef: - element = GetMemberReference(rid); - break; - case TokenType.MethodSpec: - element = GetMethodSpecification(rid); - break; - default: - return null; - } - - this.position = position; - this.context = context; - - return element; - } - - public FieldDefinition GetFieldDefinition(uint rid) - { - InitializeTypeDefinitions(); - - var field = metadata.GetFieldDefinition(rid); - if (field != null) - return field; - - return LookupField(rid); - } - - FieldDefinition LookupField(uint rid) - { - var type = metadata.GetFieldDeclaringType(rid); - if (type == null) - return null; - - InitializeCollection(type.Fields); - - return metadata.GetFieldDefinition(rid); - } - - public MethodDefinition GetMethodDefinition(uint rid) - { - InitializeTypeDefinitions(); - - var method = metadata.GetMethodDefinition(rid); - if (method != null) - return method; - - return LookupMethod(rid); - } - - MethodDefinition LookupMethod(uint rid) - { - var type = metadata.GetMethodDeclaringType(rid); - if (type == null) - return null; - - InitializeCollection(type.Methods); - - return metadata.GetMethodDefinition(rid); - } - - MethodSpecification GetMethodSpecification(uint rid) - { - if (!MoveTo(Table.MethodSpec, rid)) - return null; - - var element_method = (MethodReference)LookupToken( - ReadMetadataToken(CodedIndex.MethodDefOrRef)); - var signature = ReadBlobIndex(); - - var method_spec = ReadMethodSpecSignature(signature, element_method); - method_spec.token = new MetadataToken(TokenType.MethodSpec, rid); - return method_spec; - } - - MethodSpecification ReadMethodSpecSignature(uint signature, MethodReference method) - { - var reader = ReadSignature(signature); - const byte methodspec_sig = 0x0a; - - var call_conv = reader.ReadByte(); - - if (call_conv != methodspec_sig) - throw new NotSupportedException(); - - var instance = new GenericInstanceMethod(method); - - reader.ReadGenericInstanceSignature(method, instance); - - return instance; - } - - MemberReference GetMemberReference(uint rid) - { - InitializeMemberReferences(); - - var member = metadata.GetMemberReference(rid); - if (member != null) - return member; - - member = ReadMemberReference(rid); - if (member != null && !member.ContainsGenericParameter) - metadata.AddMemberReference(member); - return member; - } - - MemberReference ReadMemberReference(uint rid) - { - if (!MoveTo(Table.MemberRef, rid)) - return null; - - var token = ReadMetadataToken(CodedIndex.MemberRefParent); - var name = ReadString(); - var signature = ReadBlobIndex(); - - MemberReference member; - - switch (token.TokenType) - { - case TokenType.TypeDef: - case TokenType.TypeRef: - case TokenType.TypeSpec: - member = ReadTypeMemberReference(token, name, signature); - break; - case TokenType.Method: - member = ReadMethodMemberReference(token, name, signature); - break; - default: - throw new NotSupportedException(); - } - - member.token = new MetadataToken(TokenType.MemberRef, rid); - - return member; - } - - MemberReference ReadTypeMemberReference(MetadataToken type, string name, uint signature) - { - var declaring_type = GetTypeDefOrRef(type); - - if (!declaring_type.IsArray) - this.context = declaring_type; - - var member = ReadMemberReferenceSignature(signature, declaring_type); - member.Name = name; - - return member; - } - - MemberReference ReadMemberReferenceSignature(uint signature, TypeReference declaring_type) - { - var reader = ReadSignature(signature); - const byte field_sig = 0x6; - - if (reader.buffer[reader.position] == field_sig) - { - reader.position++; - var field = new FieldReference(); - field.DeclaringType = declaring_type; - field.FieldType = reader.ReadTypeSignature(); - return field; - } - else - { - var method = new MethodReference(); - method.DeclaringType = declaring_type; - reader.ReadMethodSignature(method); - return method; - } - } - - MemberReference ReadMethodMemberReference(MetadataToken token, string name, uint signature) - { - var method = GetMethodDefinition(token.RID); - - this.context = method; - - var member = ReadMemberReferenceSignature(signature, method.DeclaringType); - member.Name = name; - - return member; - } - - void InitializeMemberReferences() - { - if (metadata.MemberReferences != null) - return; - - metadata.MemberReferences = new MemberReference[image.GetTableLength(Table.MemberRef)]; - } - - public IEnumerable GetMemberReferences() - { - InitializeMemberReferences(); - - var length = image.GetTableLength(Table.MemberRef); - - var type_system = module.TypeSystem; - - var context = new MethodReference(string.Empty, type_system.Void); - context.DeclaringType = new TypeReference(string.Empty, string.Empty, module, type_system.Corlib); - - var member_references = new MemberReference[length]; - - for (uint i = 1; i <= length; i++) - { - this.context = context; - member_references[i - 1] = GetMemberReference(i); - } - - return member_references; - } - - void InitializeConstants() - { - if (metadata.Constants != null) - return; - - var length = MoveTo(Table.Constant); - - var constants = metadata.Constants = new Dictionary>(length); - - for (uint i = 1; i <= length; i++) - { - var type = (ElementType)ReadUInt16(); - var owner = ReadMetadataToken(CodedIndex.HasConstant); - var signature = ReadBlobIndex(); - - constants.Add(owner, new Row(type, signature)); - } - } - - public object ReadConstant(IConstantProvider owner) - { - InitializeConstants(); - - Row row; - if (!metadata.Constants.TryGetValue(owner.MetadataToken, out row)) - return Mixin.NoValue; - - metadata.Constants.Remove(owner.MetadataToken); - - switch (row.Col1) - { - case ElementType.Class: - case ElementType.Object: - return null; - case ElementType.String: - return ReadConstantString(ReadBlob(row.Col2)); - default: - return ReadConstantPrimitive(row.Col1, row.Col2); - } - } - - static string ReadConstantString(byte[] blob) - { - var length = blob.Length; - if ((length & 1) == 1) - length--; - - return Encoding.Unicode.GetString(blob, 0, length); - } - - object ReadConstantPrimitive(ElementType type, uint signature) - { - var reader = ReadSignature(signature); - return reader.ReadConstantSignature(type); - } - - void InitializeCustomAttributes() - { - if (metadata.CustomAttributes != null) - return; - - metadata.CustomAttributes = InitializeRanges( - Table.CustomAttribute, () => - { - var next = ReadMetadataToken(CodedIndex.HasCustomAttribute); - ReadMetadataToken(CodedIndex.CustomAttributeType); - ReadBlobIndex(); - return next; - }); - } - - public bool HasCustomAttributes(ICustomAttributeProvider owner) - { - InitializeCustomAttributes(); - - Range range; - if (!metadata.TryGetCustomAttributeRange(owner, out range)) - return false; - - return range.Length > 0; - } - - public Collection ReadCustomAttributes(ICustomAttributeProvider owner) - { - InitializeCustomAttributes(); - - Range range; - if (!metadata.TryGetCustomAttributeRange(owner, out range) - || !MoveTo(Table.CustomAttribute, range.Start)) - return new Collection(); - - var custom_attributes = new Collection((int)range.Length); - - for (int i = 0; i < range.Length; i++) - { - ReadMetadataToken(CodedIndex.HasCustomAttribute); - - var constructor = (MethodReference)LookupToken( - ReadMetadataToken(CodedIndex.CustomAttributeType)); - - var signature = ReadBlobIndex(); - - custom_attributes.Add(new CustomAttribute(signature, constructor)); - } - - metadata.RemoveCustomAttributeRange(owner); - - return custom_attributes; - } - - public byte[] ReadCustomAttributeBlob(uint signature) - { - return ReadBlob(signature); - } - - public void ReadCustomAttributeSignature(CustomAttribute attribute) - { - var reader = ReadSignature(attribute.signature); - - if (!reader.CanReadMore()) - return; - - if (reader.ReadUInt16() != 0x0001) - throw new InvalidOperationException(); - - var constructor = attribute.Constructor; - if (constructor.HasParameters) - reader.ReadCustomAttributeConstructorArguments(attribute, constructor.Parameters); - - if (!reader.CanReadMore()) - return; - - var named = reader.ReadUInt16(); - - if (named == 0) - return; - - reader.ReadCustomAttributeNamedArguments(named, ref attribute.fields, ref attribute.properties); - } - - void InitializeMarshalInfos() - { - if (metadata.FieldMarshals != null) - return; - - var length = MoveTo(Table.FieldMarshal); - - var marshals = metadata.FieldMarshals = new Dictionary(length); - - for (int i = 0; i < length; i++) - { - var token = ReadMetadataToken(CodedIndex.HasFieldMarshal); - var signature = ReadBlobIndex(); - if (token.RID == 0) - continue; - - marshals.Add(token, signature); - } - } - - public bool HasMarshalInfo(IMarshalInfoProvider owner) - { - InitializeMarshalInfos(); - - return metadata.FieldMarshals.ContainsKey(owner.MetadataToken); - } - - public MarshalInfo ReadMarshalInfo(IMarshalInfoProvider owner) - { - InitializeMarshalInfos(); - - uint signature; - if (!metadata.FieldMarshals.TryGetValue(owner.MetadataToken, out signature)) - return null; - - var reader = ReadSignature(signature); - - metadata.FieldMarshals.Remove(owner.MetadataToken); - - return reader.ReadMarshalInfo(); - } - - void InitializeSecurityDeclarations() - { - if (metadata.SecurityDeclarations != null) - return; - - metadata.SecurityDeclarations = InitializeRanges( - Table.DeclSecurity, () => - { - ReadUInt16(); - var next = ReadMetadataToken(CodedIndex.HasDeclSecurity); - ReadBlobIndex(); - return next; - }); - } - - public bool HasSecurityDeclarations(ISecurityDeclarationProvider owner) - { - InitializeSecurityDeclarations(); - - Range range; - if (!metadata.TryGetSecurityDeclarationRange(owner, out range)) - return false; - - return range.Length > 0; - } - - public Collection ReadSecurityDeclarations(ISecurityDeclarationProvider owner) - { - InitializeSecurityDeclarations(); - - Range range; - if (!metadata.TryGetSecurityDeclarationRange(owner, out range) - || !MoveTo(Table.DeclSecurity, range.Start)) - return new Collection(); - - var security_declarations = new Collection((int)range.Length); - - for (int i = 0; i < range.Length; i++) - { - var action = (SecurityAction)ReadUInt16(); - ReadMetadataToken(CodedIndex.HasDeclSecurity); - var signature = ReadBlobIndex(); - - security_declarations.Add(new SecurityDeclaration(action, signature, module)); - } - - metadata.RemoveSecurityDeclarationRange(owner); - - return security_declarations; - } - - public byte[] ReadSecurityDeclarationBlob(uint signature) - { - return ReadBlob(signature); - } - - public void ReadSecurityDeclarationSignature(SecurityDeclaration declaration) - { - var signature = declaration.signature; - var reader = ReadSignature(signature); - - if (reader.buffer[reader.position] != '.') - { - ReadXmlSecurityDeclaration(signature, declaration); - return; - } - - reader.position++; - var count = reader.ReadCompressedUInt32(); - var attributes = new Collection((int)count); - - for (int i = 0; i < count; i++) - attributes.Add(reader.ReadSecurityAttribute()); - - declaration.security_attributes = attributes; - } - - void ReadXmlSecurityDeclaration(uint signature, SecurityDeclaration declaration) - { - var blob = ReadBlob(signature); - var attributes = new Collection(1); - - var attribute = new SecurityAttribute( - module.TypeSystem.LookupType("System.Security.Permissions", "PermissionSetAttribute")); - - attribute.properties = new Collection(1); - attribute.properties.Add( - new CustomAttributeNamedArgument( - "XML", - new CustomAttributeArgument( - module.TypeSystem.String, - Encoding.Unicode.GetString(blob, 0, blob.Length)))); - - attributes.Add(attribute); - - declaration.security_attributes = attributes; - } - - public Collection ReadExportedTypes() - { - var length = MoveTo(Table.ExportedType); - if (length == 0) - return new Collection(); - - var exported_types = new Collection(length); - - for (int i = 1; i <= length; i++) - { - var attributes = (TypeAttributes)ReadUInt32(); - var identifier = ReadUInt32(); - var name = ReadString(); - var @namespace = ReadString(); - var implementation = ReadMetadataToken(CodedIndex.Implementation); - - ExportedType declaring_type = null; - IMetadataScope scope = null; - - switch (implementation.TokenType) - { - case TokenType.AssemblyRef: - case TokenType.File: - scope = GetExportedTypeScope(implementation); - break; - case TokenType.ExportedType: - // FIXME: if the table is not properly sorted - declaring_type = exported_types[(int)implementation.RID - 1]; - break; - } - - var exported_type = new ExportedType(@namespace, name, module, scope) - { - Attributes = attributes, - Identifier = (int)identifier, - DeclaringType = declaring_type, - }; - exported_type.token = new MetadataToken(TokenType.ExportedType, i); - - exported_types.Add(exported_type); - } - - return exported_types; - } - - IMetadataScope GetExportedTypeScope(MetadataToken token) - { - var position = this.position; - IMetadataScope scope; - - switch (token.TokenType) - { - case TokenType.AssemblyRef: - InitializeAssemblyReferences(); - scope = metadata.AssemblyReferences[(int)token.RID - 1]; - break; - case TokenType.File: - InitializeModuleReferences(); - scope = GetModuleReferenceFromFile(token); - break; - default: - throw new NotSupportedException(); - } - - this.position = position; - return scope; - } - - ModuleReference GetModuleReferenceFromFile(MetadataToken token) - { - if (!MoveTo(Table.File, token.RID)) - return null; - - ReadUInt32(); - var file_name = ReadString(); - var modules = module.ModuleReferences; - - ModuleReference reference; - for (int i = 0; i < modules.Count; i++) - { - reference = modules[i]; - if (reference.Name == file_name) - return reference; - } - - reference = new ModuleReference(file_name); - modules.Add(reference); - return reference; - } - - static void InitializeCollection(object o) - { - } - } - - sealed class SignatureReader : ByteBuffer - { - - readonly MetadataReader reader; - readonly uint start, sig_length; - - TypeSystem TypeSystem - { - get { return reader.module.TypeSystem; } - } - - public SignatureReader(uint blob, MetadataReader reader) - : base(reader.buffer) - { - this.reader = reader; - - MoveToBlob(blob); - - this.sig_length = ReadCompressedUInt32(); - this.start = (uint)position; - } - - void MoveToBlob(uint blob) - { - position = (int)(reader.image.BlobHeap.Offset + blob); - } - - MetadataToken ReadTypeTokenSignature() - { - return Mixin.GetMetadataToken(CodedIndex.TypeDefOrRef, ReadCompressedUInt32()); - } - - GenericParameter GetGenericParameter(GenericParameterType type, uint var) - { - var context = reader.context; - int index = (int)var; - - if (context == null) - return GetUnboundGenericParameter(type, index); - - IGenericParameterProvider provider; - - switch (type) - { - case GenericParameterType.Type: - provider = context.Type; - break; - case GenericParameterType.Method: - provider = context.Method; - break; - default: - throw new NotSupportedException(); - } - - if (!context.IsDefinition) - CheckGenericContext(provider, index); - - if (index >= provider.GenericParameters.Count) - return GetUnboundGenericParameter(type, index); - - return provider.GenericParameters[index]; - } - - GenericParameter GetUnboundGenericParameter(GenericParameterType type, int index) - { - return new GenericParameter(index, type, reader.module); - } - - static void CheckGenericContext(IGenericParameterProvider owner, int index) - { - var owner_parameters = owner.GenericParameters; - - for (int i = owner_parameters.Count; i <= index; i++) - owner_parameters.Add(new GenericParameter(owner)); - } - - public void ReadGenericInstanceSignature(IGenericParameterProvider provider, IGenericInstance instance) - { - var arity = ReadCompressedUInt32(); - - if (!provider.IsDefinition) - CheckGenericContext(provider, (int)arity - 1); - - var instance_arguments = instance.GenericArguments; - - for (int i = 0; i < arity; i++) - instance_arguments.Add(ReadTypeSignature()); - } - - ArrayType ReadArrayTypeSignature() - { - var array = new ArrayType(ReadTypeSignature()); - - var rank = ReadCompressedUInt32(); - - var sizes = new uint[ReadCompressedUInt32()]; - for (int i = 0; i < sizes.Length; i++) - sizes[i] = ReadCompressedUInt32(); - - var low_bounds = new int[ReadCompressedUInt32()]; - for (int i = 0; i < low_bounds.Length; i++) - low_bounds[i] = ReadCompressedInt32(); - - array.Dimensions.Clear(); - - for (int i = 0; i < rank; i++) - { - int? lower = null, upper = null; - - if (i < low_bounds.Length) - lower = low_bounds[i]; - - if (i < sizes.Length) - upper = lower + (int)sizes[i] - 1; - - array.Dimensions.Add(new ArrayDimension(lower, upper)); - } - - return array; - } - - TypeReference GetTypeDefOrRef(MetadataToken token) - { - return reader.GetTypeDefOrRef(token); - } - - public TypeReference ReadTypeSignature() - { - return ReadTypeSignature((ElementType)ReadByte()); - } - - TypeReference ReadTypeSignature(ElementType etype) - { - switch (etype) - { - case ElementType.ValueType: - { - var value_type = GetTypeDefOrRef(ReadTypeTokenSignature()); - value_type.IsValueType = true; - return value_type; - } - case ElementType.Class: - return GetTypeDefOrRef(ReadTypeTokenSignature()); - case ElementType.Ptr: - return new PointerType(ReadTypeSignature()); - case ElementType.FnPtr: - { - var fptr = new FunctionPointerType(); - ReadMethodSignature(fptr); - return fptr; - } - case ElementType.ByRef: - return new ByReferenceType(ReadTypeSignature()); - case ElementType.Pinned: - return new PinnedType(ReadTypeSignature()); - case ElementType.SzArray: - return new ArrayType(ReadTypeSignature()); - case ElementType.Array: - return ReadArrayTypeSignature(); - case ElementType.CModOpt: - return new OptionalModifierType( - GetTypeDefOrRef(ReadTypeTokenSignature()), ReadTypeSignature()); - case ElementType.CModReqD: - return new RequiredModifierType( - GetTypeDefOrRef(ReadTypeTokenSignature()), ReadTypeSignature()); - case ElementType.Sentinel: - return new SentinelType(ReadTypeSignature()); - case ElementType.Var: - return GetGenericParameter(GenericParameterType.Type, ReadCompressedUInt32()); - case ElementType.MVar: - return GetGenericParameter(GenericParameterType.Method, ReadCompressedUInt32()); - case ElementType.GenericInst: - { - var is_value_type = ReadByte() == (byte)ElementType.ValueType; - var element_type = GetTypeDefOrRef(ReadTypeTokenSignature()); - var generic_instance = new GenericInstanceType(element_type); - - ReadGenericInstanceSignature(element_type, generic_instance); - - if (is_value_type) - { - generic_instance.IsValueType = true; - element_type.GetElementType().IsValueType = true; - } - - return generic_instance; - } - case ElementType.Object: return TypeSystem.Object; - case ElementType.Void: return TypeSystem.Void; - case ElementType.TypedByRef: return TypeSystem.TypedReference; - case ElementType.I: return TypeSystem.IntPtr; - case ElementType.U: return TypeSystem.UIntPtr; - default: return GetPrimitiveType(etype); - } - } - - public void ReadMethodSignature(IMethodSignature method) - { - var calling_convention = ReadByte(); - - const byte has_this = 0x20; - const byte explicit_this = 0x40; - - if ((calling_convention & has_this) != 0) - { - method.HasThis = true; - calling_convention = (byte)(calling_convention & ~has_this); - } - - if ((calling_convention & explicit_this) != 0) - { - method.ExplicitThis = true; - calling_convention = (byte)(calling_convention & ~explicit_this); - } - - method.CallingConvention = (MethodCallingConvention)calling_convention; - - var generic_context = method as MethodReference; - if (generic_context != null && !generic_context.DeclaringType.IsArray) - reader.context = generic_context; - - if ((calling_convention & 0x10) != 0) - { - var arity = ReadCompressedUInt32(); - - if (generic_context != null && !generic_context.IsDefinition) - CheckGenericContext(generic_context, (int)arity - 1); - } - - var param_count = ReadCompressedUInt32(); - - method.MethodReturnType.ReturnType = ReadTypeSignature(); - - if (param_count == 0) - return; - - Collection parameters; - - var method_ref = method as MethodReference; - if (method_ref != null) - parameters = method_ref.parameters = new ParameterDefinitionCollection(method, (int)param_count); - else - parameters = method.Parameters; - - for (int i = 0; i < param_count; i++) - parameters.Add(new ParameterDefinition(ReadTypeSignature())); - } - - public object ReadConstantSignature(ElementType type) - { - return ReadPrimitiveValue(type); - } - - public void ReadCustomAttributeConstructorArguments(CustomAttribute attribute, Collection parameters) - { - var count = parameters.Count; - if (count == 0) - return; - - attribute.arguments = new Collection(count); - - for (int i = 0; i < count; i++) - attribute.arguments.Add( - ReadCustomAttributeFixedArgument(parameters[i].ParameterType)); - } - - CustomAttributeArgument ReadCustomAttributeFixedArgument(TypeReference type) - { - if (type.IsArray) - return ReadCustomAttributeFixedArrayArgument((ArrayType)type); - - return ReadCustomAttributeElement(type); - } - - public void ReadCustomAttributeNamedArguments(ushort count, ref Collection fields, ref Collection properties) - { - for (int i = 0; i < count; i++) - ReadCustomAttributeNamedArgument(ref fields, ref properties); - } - - void ReadCustomAttributeNamedArgument(ref Collection fields, ref Collection properties) - { - var kind = ReadByte(); - var type = ReadCustomAttributeFieldOrPropType(); - var name = ReadUTF8String(); - - Collection container; - switch (kind) - { - case 0x53: - container = GetCustomAttributeNamedArgumentCollection(ref fields); - break; - case 0x54: - container = GetCustomAttributeNamedArgumentCollection(ref properties); - break; - default: - throw new NotSupportedException(); - } - - container.Add(new CustomAttributeNamedArgument(name, ReadCustomAttributeFixedArgument(type))); - } - - static Collection GetCustomAttributeNamedArgumentCollection(ref Collection collection) - { - if (collection != null) - return collection; - - return collection = new Collection(); - } - - CustomAttributeArgument ReadCustomAttributeFixedArrayArgument(ArrayType type) - { - var length = ReadUInt32(); - - if (length == 0xffffffff) - return new CustomAttributeArgument(type, null); - - if (length == 0) - return new CustomAttributeArgument(type, Empty.Array); - - var arguments = new CustomAttributeArgument[length]; - var element_type = type.ElementType; - - for (int i = 0; i < length; i++) - arguments[i] = ReadCustomAttributeElement(element_type); - - return new CustomAttributeArgument(type, arguments); - } - - CustomAttributeArgument ReadCustomAttributeElement(TypeReference type) - { - if (type.IsArray) - return ReadCustomAttributeFixedArrayArgument((ArrayType)type); - - return new CustomAttributeArgument( - type, - type.etype == ElementType.Object - ? ReadCustomAttributeElement(ReadCustomAttributeFieldOrPropType()) - : ReadCustomAttributeElementValue(type)); - } - - object ReadCustomAttributeElementValue(TypeReference type) - { - var etype = type.etype; - - switch (etype) - { - case ElementType.String: - return ReadUTF8String(); - case ElementType.None: - if (Mixin.IsTypeOf(type,"System", "Type")) - return ReadTypeReference(); - - return ReadCustomAttributeEnum(type); - default: - return ReadPrimitiveValue(etype); - } - } - - object ReadPrimitiveValue(ElementType type) - { - switch (type) - { - case ElementType.Boolean: - return ReadByte() == 1; - case ElementType.I1: - return (sbyte)ReadByte(); - case ElementType.U1: - return ReadByte(); - case ElementType.Char: - return (char)ReadUInt16(); - case ElementType.I2: - return ReadInt16(); - case ElementType.U2: - return ReadUInt16(); - case ElementType.I4: - return ReadInt32(); - case ElementType.U4: - return ReadUInt32(); - case ElementType.I8: - return ReadInt64(); - case ElementType.U8: - return ReadUInt64(); - case ElementType.R4: - return ReadSingle(); - case ElementType.R8: - return ReadDouble(); - default: - throw new NotImplementedException(type.ToString()); - } - } - - TypeReference GetPrimitiveType(ElementType etype) - { - switch (etype) - { - case ElementType.Boolean: - return TypeSystem.Boolean; - case ElementType.Char: - return TypeSystem.Char; - case ElementType.I1: - return TypeSystem.SByte; - case ElementType.U1: - return TypeSystem.Byte; - case ElementType.I2: - return TypeSystem.Int16; - case ElementType.U2: - return TypeSystem.UInt16; - case ElementType.I4: - return TypeSystem.Int32; - case ElementType.U4: - return TypeSystem.UInt32; - case ElementType.I8: - return TypeSystem.Int64; - case ElementType.U8: - return TypeSystem.UInt64; - case ElementType.R4: - return TypeSystem.Single; - case ElementType.R8: - return TypeSystem.Double; - case ElementType.String: - return TypeSystem.String; - default: - throw new NotImplementedException(etype.ToString()); - } - } - - TypeReference ReadCustomAttributeFieldOrPropType() - { - var etype = (ElementType)ReadByte(); - - switch (etype) - { - case ElementType.Boxed: - return TypeSystem.Object; - case ElementType.SzArray: - return new ArrayType(ReadCustomAttributeFieldOrPropType()); - case ElementType.Enum: - return ReadTypeReference(); - case ElementType.Type: - return TypeSystem.LookupType("System", "Type"); - default: - return GetPrimitiveType(etype); - } - } - - public TypeReference ReadTypeReference() - { - return TypeParser.ParseType(reader.module, ReadUTF8String()); - } - - object ReadCustomAttributeEnum(TypeReference enum_type) - { - try - { - TypeDefinition type = null; - type = Mixin.CheckedResolve(enum_type); - if (!type.IsEnum) - throw new ArgumentException(); - return ReadCustomAttributeElementValue(Mixin.GetEnumUnderlyingType(type)); - } - catch - { - //Resolve failed - string name = enum_type.FullName + ", " + enum_type.scope.Name; - Type type = Type.GetType(name); - if (type == null || !type.IsEnum) - return new ArgumentException(); - var fields = type.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public); - Type eType = null; - foreach(var i in fields) - { - eType = i.FieldType; - break; - } - - object val; - if(eType == typeof(int)) - { - val = ReadPrimitiveValue(ElementType.I4); - } - else if (eType == typeof(long)) - { - val = ReadPrimitiveValue(ElementType.I8); - } - else if (eType == typeof(short)) - { - val = ReadPrimitiveValue(ElementType.I2); - } - else if (eType == typeof(byte)) - { - val = ReadPrimitiveValue(ElementType.U1); - } - else if (eType == typeof(uint)) - { - val = ReadPrimitiveValue(ElementType.U4); - } - else if (eType == typeof(ulong)) - { - val = ReadPrimitiveValue(ElementType.U8); - } - else if (eType == typeof(ushort)) - { - val = ReadPrimitiveValue(ElementType.U2); - } - else - { - val = ReadPrimitiveValue(ElementType.Void); - } - - return Enum.ToObject(type, val); - } - - } - - public SecurityAttribute ReadSecurityAttribute() - { - var attribute = new SecurityAttribute(ReadTypeReference()); - - ReadCompressedUInt32(); - - ReadCustomAttributeNamedArguments( - (ushort)ReadCompressedUInt32(), - ref attribute.fields, - ref attribute.properties); - - return attribute; - } - - public MarshalInfo ReadMarshalInfo() - { - var native = ReadNativeType(); - switch (native) - { - case NativeType.Array: - { - var array = new ArrayMarshalInfo(); - if (CanReadMore()) - array.element_type = ReadNativeType(); - if (CanReadMore()) - array.size_parameter_index = (int)ReadCompressedUInt32(); - if (CanReadMore()) - array.size = (int)ReadCompressedUInt32(); - if (CanReadMore()) - array.size_parameter_multiplier = (int)ReadCompressedUInt32(); - return array; - } - case NativeType.SafeArray: - { - var array = new SafeArrayMarshalInfo(); - if (CanReadMore()) - array.element_type = ReadVariantType(); - return array; - } - case NativeType.FixedArray: - { - var array = new FixedArrayMarshalInfo(); - if (CanReadMore()) - array.size = (int)ReadCompressedUInt32(); - if (CanReadMore()) - array.element_type = ReadNativeType(); - return array; - } - case NativeType.FixedSysString: - { - var sys_string = new FixedSysStringMarshalInfo(); - if (CanReadMore()) - sys_string.size = (int)ReadCompressedUInt32(); - return sys_string; - } - case NativeType.CustomMarshaler: - { - var marshaler = new CustomMarshalInfo(); - var guid_value = ReadUTF8String(); - marshaler.guid = !string.IsNullOrEmpty(guid_value) ? new Guid(guid_value) : Guid.Empty; - marshaler.unmanaged_type = ReadUTF8String(); - marshaler.managed_type = ReadTypeReference(); - marshaler.cookie = ReadUTF8String(); - return marshaler; - } - default: - return new MarshalInfo(native); - } - } - - NativeType ReadNativeType() - { - return (NativeType)ReadByte(); - } - - VariantType ReadVariantType() - { - return (VariantType)ReadByte(); - } - - string ReadUTF8String() - { - if (buffer[position] == 0xff) - { - position++; - return null; - } - - var length = (int)ReadCompressedUInt32(); - if (length == 0) - return string.Empty; - - var @string = Encoding.UTF8.GetString(buffer, position, - buffer[position + length - 1] == 0 ? length - 1 : length); - - position += length; - return @string; - } - - public bool CanReadMore() - { - return position - start < sig_length; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyWriter.cs deleted file mode 100644 index 824dd349..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyWriter.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// AssemblyWriter.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -using Mono.Collections.Generic; -using Mono.Cecil.Cil; -using Mono.Cecil.Metadata; -using Mono.Cecil.PE; - -using RVA = System.UInt32; -using RID = System.UInt32; -using CodedRID = System.UInt32; -using StringIndex = System.UInt32; -using BlobIndex = System.UInt32; - -namespace Mono.Cecil { - -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/BaseAssemblyResolver.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/BaseAssemblyResolver.cs deleted file mode 100644 index 7bcafc9b..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/BaseAssemblyResolver.cs +++ /dev/null @@ -1,172 +0,0 @@ -// -// BaseAssemblyResolver.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -using Mono.Collections.Generic; - -namespace Mono.Cecil { - - public delegate AssemblyDefinition AssemblyResolveEventHandler (object sender, AssemblyNameReference reference); - - public sealed class AssemblyResolveEventArgs : EventArgs { - - readonly AssemblyNameReference reference; - - public AssemblyNameReference AssemblyReference { - get { return reference; } - } - - public AssemblyResolveEventArgs (AssemblyNameReference reference) - { - this.reference = reference; - } - } - - - public class AssemblyResolutionException : FileNotFoundException { - - readonly AssemblyNameReference reference; - - public AssemblyNameReference AssemblyReference { - get { return reference; } - } - - public AssemblyResolutionException (AssemblyNameReference reference) - : base (string.Format ("Failed to resolve assembly: '{0}'", reference)) - { - this.reference = reference; - } - - - } - - public abstract class BaseAssemblyResolver : IAssemblyResolver { - - static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null; - - readonly Collection directories; - - - - public void AddSearchDirectory (string directory) - { - directories.Add (directory); - } - - public void RemoveSearchDirectory (string directory) - { - directories.Remove (directory); - } - - public string [] GetSearchDirectories () - { - var directories = new string [this.directories.size]; - Array.Copy (this.directories.items, directories, directories.Length); - return directories; - } - - public virtual AssemblyDefinition Resolve (string fullName) - { - return Resolve (fullName, new ReaderParameters ()); - } - - public virtual AssemblyDefinition Resolve (string fullName, ReaderParameters parameters) - { - if (fullName == null) - throw new ArgumentNullException ("fullName"); - - return Resolve (AssemblyNameReference.Parse (fullName), parameters); - } - - public event AssemblyResolveEventHandler ResolveFailure; - - protected BaseAssemblyResolver () - { - directories = new Collection (2) { ".", "bin" }; - } - - AssemblyDefinition GetAssembly (string file, ReaderParameters parameters) - { - if (parameters.AssemblyResolver == null) - parameters.AssemblyResolver = this; - - return ModuleDefinition.ReadModule (file, parameters).Assembly; - } - - public virtual AssemblyDefinition Resolve (AssemblyNameReference name) - { - return Resolve (name, new ReaderParameters ()); - } - - public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters) - { - if (name == null) - throw new ArgumentNullException ("name"); - if (parameters == null) - parameters = new ReaderParameters (); - - var assembly = SearchDirectory (name, directories, parameters); - if (assembly != null) - return assembly; - - - - if (ResolveFailure != null) { - assembly = ResolveFailure (this, name); - if (assembly != null) - return assembly; - } - - throw new AssemblyResolutionException (name); - } - - AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable directories, ReaderParameters parameters) - { - var extensions = new [] { ".exe", ".dll" }; - foreach (var directory in directories) { - foreach (var extension in extensions) { - string file = Path.Combine (directory, name.Name + extension); - if (File.Exists (file)) - return GetAssembly (file, parameters); - } - } - - return null; - } - - static bool IsZero (Version version) - { - return version == null || (version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0); - } - - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/DefaultAssemblyResolver.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/DefaultAssemblyResolver.cs deleted file mode 100644 index e0baedf7..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/DefaultAssemblyResolver.cs +++ /dev/null @@ -1,70 +0,0 @@ -// -// DefaultAssemblyResolver.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; - -namespace Mono.Cecil { - - public class DefaultAssemblyResolver : BaseAssemblyResolver { - - readonly IDictionary cache; - - public DefaultAssemblyResolver () - { - cache = new Dictionary (StringComparer.Ordinal); - } - - public override AssemblyDefinition Resolve (AssemblyNameReference name) - { - if (name == null) - throw new ArgumentNullException ("name"); - - AssemblyDefinition assembly; - if (cache.TryGetValue (name.FullName, out assembly)) - return assembly; - - assembly = base.Resolve (name); - cache [name.FullName] = assembly; - - return assembly; - } - - protected void RegisterAssembly (AssemblyDefinition assembly) - { - if (assembly == null) - throw new ArgumentNullException ("assembly"); - - var name = assembly.Name.FullName; - if (cache.ContainsKey (name)) - return; - - cache [name] = assembly; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EmbeddedResource.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/EmbeddedResource.cs deleted file mode 100644 index e12dd0b3..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EmbeddedResource.cs +++ /dev/null @@ -1,105 +0,0 @@ -// -// EmbeddedResource.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; - -namespace Mono.Cecil { - - public sealed class EmbeddedResource : Resource { - - readonly MetadataReader reader; - - uint? offset; - byte [] data; - Stream stream; - - public override ResourceType ResourceType { - get { return ResourceType.Embedded; } - } - - public EmbeddedResource (string name, ManifestResourceAttributes attributes, byte [] data) : - base (name, attributes) - { - this.data = data; - } - - public EmbeddedResource (string name, ManifestResourceAttributes attributes, Stream stream) : - base (name, attributes) - { - this.stream = stream; - } - - internal EmbeddedResource (string name, ManifestResourceAttributes attributes, uint offset, MetadataReader reader) - : base (name, attributes) - { - this.offset = offset; - this.reader = reader; - } - - public Stream GetResourceStream () - { - if (stream != null) - return stream; - - if (data != null) - return new MemoryStream (data); - - if (offset.HasValue) - return reader.GetManagedResourceStream (offset.Value); - - throw new InvalidOperationException (); - } - - public byte [] GetResourceData () - { - if (stream != null) - return ReadStream (stream); - - if (data != null) - return data; - - if (offset.HasValue) - return reader.GetManagedResourceStream (offset.Value).ToArray (); - - throw new InvalidOperationException (); - } - - static byte [] ReadStream (Stream stream) - { - var length = (int) stream.Length; - var data = new byte [length]; - int offset = 0, read; - - while ((read = stream.Read (data, offset, length - offset)) > 0) - offset += read; - - return data; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventAttributes.cs deleted file mode 100644 index 815efa57..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventAttributes.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// EventAttributes.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - [Flags] - public enum EventAttributes : ushort { - None = 0x0000, - SpecialName = 0x0200, // Event is special - RTSpecialName = 0x0400 // CLI provides 'special' behavior, depending upon the name of the event - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventReference.cs deleted file mode 100644 index 8952002d..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventReference.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// EventReference.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - public abstract class EventReference : MemberReference { - - TypeReference event_type; - - public TypeReference EventType { - get { return event_type; } - set { event_type = value; } - } - - public override string FullName { - get { return event_type.FullName + " " + MemberFullName (); } - } - - protected EventReference (string name, TypeReference eventType) - : base (name) - { - if (eventType == null) - throw new ArgumentNullException ("eventType"); - - event_type = eventType; - } - - public abstract EventDefinition Resolve (); - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ExportedType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ExportedType.cs deleted file mode 100644 index 5cc7f2b0..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ExportedType.cs +++ /dev/null @@ -1,249 +0,0 @@ -// -// ExportedType.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - public class ExportedType : IMetadataTokenProvider { - - string @namespace; - string name; - uint attributes; - IMetadataScope scope; - ModuleDefinition module; - int identifier; - ExportedType declaring_type; - internal MetadataToken token; - - public string Namespace { - get { return @namespace; } - set { @namespace = value; } - } - - public string Name { - get { return name; } - set { name = value; } - } - - public TypeAttributes Attributes { - get { return (TypeAttributes) attributes; } - set { attributes = (uint) value; } - } - - public IMetadataScope Scope { - get { - if (declaring_type != null) - return declaring_type.Scope; - - return scope; - } - } - - public ExportedType DeclaringType { - get { return declaring_type; } - set { declaring_type = value; } - } - - public MetadataToken MetadataToken { - get { return token; } - set { token = value; } - } - - public int Identifier { - get { return identifier; } - set { identifier = value; } - } - - #region TypeAttributes - - public bool IsNotPublic { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); } - } - - public bool IsPublic { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); } - } - - public bool IsNestedPublic { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); } - } - - public bool IsNestedPrivate { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); } - } - - public bool IsNestedFamily { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); } - } - - public bool IsNestedAssembly { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); } - } - - public bool IsNestedFamilyAndAssembly { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); } - } - - public bool IsNestedFamilyOrAssembly { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); } - } - - public bool IsAutoLayout { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); } - } - - public bool IsSequentialLayout { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); } - } - - public bool IsExplicitLayout { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); } - } - - public bool IsClass { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); } - } - - public bool IsInterface { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); } - } - - public bool IsAbstract { - get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.Abstract); } - set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.Abstract, value); } - } - - public bool IsSealed { - get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.Sealed); } - set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.Sealed, value); } - } - - public bool IsSpecialName { - get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.SpecialName); } - set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.SpecialName, value); } - } - - public bool IsImport { - get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.Import); } - set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.Import, value); } - } - - public bool IsSerializable { - get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.Serializable); } - set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.Serializable, value); } - } - - public bool IsAnsiClass { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); } - } - - public bool IsUnicodeClass { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); } - } - - public bool IsAutoClass { - get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); } - } - - public bool IsBeforeFieldInit { - get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.BeforeFieldInit); } - set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.BeforeFieldInit, value); } - } - - public bool IsRuntimeSpecialName { - get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.RTSpecialName); } - set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.RTSpecialName, value); } - } - - public bool HasSecurity { - get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.HasSecurity); } - set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.HasSecurity, value); } - } - - #endregion - - public bool IsForwarder { - get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.Forwarder); } - set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.Forwarder, value); } - } - - public string FullName { - get { - if (declaring_type != null) - return declaring_type.FullName + "/" + name; - - if (string.IsNullOrEmpty (@namespace)) - return name; - - return @namespace + "." + name; - } - } - - public ExportedType (string @namespace, string name, ModuleDefinition module, IMetadataScope scope) - { - this.@namespace = @namespace; - this.name = name; - this.scope = scope; - this.module = module; - } - - public override string ToString () - { - return FullName; - } - - public TypeDefinition Resolve () - { - return module.Resolve (CreateReference ()); - } - - internal TypeReference CreateReference () - { - return new TypeReference (@namespace, name, module, scope) { - DeclaringType = declaring_type != null ? declaring_type.CreateReference () : null, - }; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldDefinition.cs deleted file mode 100644 index f90e8cb7..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldDefinition.cs +++ /dev/null @@ -1,271 +0,0 @@ -// -// FieldDefinition.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using Mono.Collections.Generic; - -namespace Mono.Cecil { - - public sealed class FieldDefinition : FieldReference, IMemberDefinition, IConstantProvider, IMarshalInfoProvider { - - ushort attributes; - Collection custom_attributes; - - int offset = Mixin.NotResolvedMarker; - - internal int rva = Mixin.NotResolvedMarker; - byte [] initial_value; - - object constant = Mixin.NotResolved; - - MarshalInfo marshal_info; - - void ResolveLayout () - { - if (offset != Mixin.NotResolvedMarker) - return; - - if (!HasImage) { - offset = Mixin.NoDataMarker; - return; - } - - offset = Module.Read (this, (field, reader) => reader.ReadFieldLayout (field)); - } - - public bool HasLayoutInfo { - get { - if (offset >= 0) - return true; - - ResolveLayout (); - - return offset >= 0; - } - } - - public int Offset { - get { - if (offset >= 0) - return offset; - - ResolveLayout (); - - return offset >= 0 ? offset : -1; - } - set { offset = value; } - } - - void ResolveRVA () - { - if (rva != Mixin.NotResolvedMarker) - return; - - if (!HasImage) - return; - - rva = Module.Read (this, (field, reader) => reader.ReadFieldRVA (field)); - } - - public int RVA { - get { - if (rva > 0) - return rva; - - ResolveRVA (); - - return rva > 0 ? rva : 0; - } - } - - public byte [] InitialValue { - get { - if (initial_value != null) - return initial_value; - - ResolveRVA (); - - if (initial_value == null) - initial_value = Empty.Array; - - return initial_value; - } - set { initial_value = value; } - } - - public FieldAttributes Attributes { - get { return (FieldAttributes) attributes; } - set { attributes = (ushort) value; } - } - - public bool HasConstant { - get { - Mixin.ResolveConstant(this, ref constant, Module); - - return constant != Mixin.NoValue; - } - set { if (!value) constant = Mixin.NoValue; } - } - - public object Constant { - get { return HasConstant ? constant : null; } - set { constant = value; } - } - - public bool HasCustomAttributes { - get { - if (custom_attributes != null) - return custom_attributes.Count > 0; - - return Mixin.GetHasCustomAttributes(this, Module); - } - } - - public Collection CustomAttributes { - get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } - } - - public bool HasMarshalInfo { - get { - if (marshal_info != null) - return true; - - return Mixin.GetHasMarshalInfo(this, Module); - } - } - - public MarshalInfo MarshalInfo { - get { return marshal_info ?? (Mixin.GetMarshalInfo(this, ref marshal_info, Module)); } - set { marshal_info = value; } - } - - #region FieldAttributes - - public bool IsCompilerControlled { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled, value); } - } - - public bool IsPrivate { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private, value); } - } - - public bool IsFamilyAndAssembly { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem, value); } - } - - public bool IsAssembly { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly, value); } - } - - public bool IsFamily { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family, value); } - } - - public bool IsFamilyOrAssembly { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem, value); } - } - - public bool IsPublic { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public, value); } - } - - public bool IsStatic { - get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.Static); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.Static, value); } - } - - public bool IsInitOnly { - get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.InitOnly); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.InitOnly, value); } - } - - public bool IsLiteral { - get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.Literal); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.Literal, value); } - } - - public bool IsNotSerialized { - get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.NotSerialized); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.NotSerialized, value); } - } - - public bool IsSpecialName { - get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.SpecialName); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.SpecialName, value); } - } - - public bool IsPInvokeImpl { - get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.PInvokeImpl); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.PInvokeImpl, value); } - } - - public bool IsRuntimeSpecialName { - get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.RTSpecialName); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.RTSpecialName, value); } - } - - public bool HasDefault { - get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.HasDefault); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.HasDefault, value); } - } - - #endregion - - public override bool IsDefinition { - get { return true; } - } - - public new TypeDefinition DeclaringType { - get { return (TypeDefinition) base.DeclaringType; } - set { base.DeclaringType = value; } - } - - public FieldDefinition (string name, FieldAttributes attributes, TypeReference fieldType) - : base (name, fieldType) - { - this.attributes = (ushort) attributes; - } - - public override FieldDefinition Resolve () - { - return this; - } - } - - static partial class Mixin { - - public const int NotResolvedMarker = -2; - public const int NoDataMarker = -1; - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldReference.cs deleted file mode 100644 index be58d3d0..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldReference.cs +++ /dev/null @@ -1,83 +0,0 @@ -// -// FieldReference.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - public class FieldReference : MemberReference { - - TypeReference field_type; - - public TypeReference FieldType { - get { return field_type; } - set { field_type = value; } - } - - public override string FullName { - get { return field_type.FullName + " " + MemberFullName (); } - } - - internal override bool ContainsGenericParameter { - get { return field_type.ContainsGenericParameter || base.ContainsGenericParameter; } - } - - internal FieldReference () - { - this.token = new MetadataToken (TokenType.MemberRef); - } - - public FieldReference (string name, TypeReference fieldType) - : base (name) - { - if (fieldType == null) - throw new ArgumentNullException ("fieldType"); - - this.field_type = fieldType; - this.token = new MetadataToken (TokenType.MemberRef); - } - - public FieldReference (string name, TypeReference fieldType, TypeReference declaringType) - : this (name, fieldType) - { - if (declaringType == null) - throw new ArgumentNullException("declaringType"); - - this.DeclaringType = declaringType; - } - - public virtual FieldDefinition Resolve () - { - var module = this.Module; - if (module == null) - throw new NotSupportedException (); - - return module.Resolve (this); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FileAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FileAttributes.cs deleted file mode 100644 index 4d3b6ca7..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FileAttributes.cs +++ /dev/null @@ -1,35 +0,0 @@ -// -// FileAttributes.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - enum FileAttributes : uint { - ContainsMetaData = 0x0000, // This is not a resource file - ContainsNoMetaData = 0x0001, // This is a resource file or other non-metadata-containing file - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceMethod.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceMethod.cs deleted file mode 100644 index 12dcd21c..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceMethod.cs +++ /dev/null @@ -1,95 +0,0 @@ -// -// GenericInstanceMethod.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Text; - -using Mono.Collections.Generic; - -namespace Mono.Cecil -{ - - public sealed class GenericInstanceMethod : MethodSpecification, IGenericInstance, IGenericContext - { - - Collection arguments; - - public bool HasGenericArguments - { - get { return !Mixin.IsNullOrEmpty(arguments); } - } - - public Collection GenericArguments - { - get { return arguments ?? (arguments = new Collection()); } - } - - public override bool IsGenericInstance - { - get { return true; } - } - - IGenericParameterProvider IGenericContext.Method - { - get { return ElementMethod; } - } - - IGenericParameterProvider IGenericContext.Type - { - get { return ElementMethod.DeclaringType; } - } - - internal override bool ContainsGenericParameter - { - get { return Mixin.ContainsGenericParameter(this) || base.ContainsGenericParameter; } - } - - public override string FullName - { - get - { - var signature = new StringBuilder(); - var method = this.ElementMethod; - signature.Append(method.ReturnType.FullName) - .Append(" ") - .Append(method.DeclaringType.FullName) - .Append("::") - .Append(method.Name); - Mixin.GenericInstanceFullName(this, signature); - Mixin.MethodSignatureFullName(this, signature); - return signature.ToString(); - - } - } - - public GenericInstanceMethod(MethodReference method) - : base(method) - { - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceType.cs deleted file mode 100644 index 1e509d63..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceType.cs +++ /dev/null @@ -1,93 +0,0 @@ -// -// GenericInstanceType.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Text; - -using Mono.Collections.Generic; - -using MD = Mono.Cecil.Metadata; - -namespace Mono.Cecil -{ - - public sealed class GenericInstanceType : TypeSpecification, IGenericInstance, IGenericContext - { - - Collection arguments; - - public bool HasGenericArguments - { - get { return !Mixin.IsNullOrEmpty(arguments); } - } - - public Collection GenericArguments - { - get { return arguments ?? (arguments = new Collection()); } - } - - public override TypeReference DeclaringType - { - get { return ElementType.DeclaringType; } - set { throw new NotSupportedException(); } - } - - public override string FullName - { - get - { - var name = new StringBuilder(); - name.Append(base.FullName); - Mixin.GenericInstanceFullName(this, name); - return name.ToString(); - } - } - - public override bool IsGenericInstance - { - get { return true; } - } - - internal override bool ContainsGenericParameter - { - get { return Mixin.ContainsGenericParameter(this) || base.ContainsGenericParameter; } - } - - IGenericParameterProvider IGenericContext.Type - { - get { return ElementType; } - } - - public GenericInstanceType(TypeReference type) - : base(type) - { - base.IsValueType = type.IsValueType; - this.etype = MD.ElementType.GenericInst; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameterAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameterAttributes.cs deleted file mode 100644 index 6d77956d..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameterAttributes.cs +++ /dev/null @@ -1,45 +0,0 @@ -// -// GenericParameterAttributes.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - [Flags] - public enum GenericParameterAttributes : ushort { - VarianceMask = 0x0003, - NonVariant = 0x0000, - Covariant = 0x0001, - Contravariant = 0x0002, - - SpecialConstraintMask = 0x001c, - ReferenceTypeConstraint = 0x0004, - NotNullableValueTypeConstraint = 0x0008, - DefaultConstructorConstraint = 0x0010 - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IConstantProvider.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IConstantProvider.cs deleted file mode 100644 index def7fb35..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IConstantProvider.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// IConstantProvider.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public interface IConstantProvider : IMetadataTokenProvider { - - bool HasConstant { get; set; } - object Constant { get; set; } - } - - static partial class Mixin { - - internal static object NoValue = new object (); - internal static object NotResolved = new object (); - - public static void ResolveConstant ( - IConstantProvider self, - ref object constant, - ModuleDefinition module) - { - lock (module.SyncRoot) { - if (constant != Mixin.NotResolved) - return; - if (Mixin.HasImage (module)) - constant = module.Read (self, (provider, reader) => reader.ReadConstant (provider)); - else - constant = Mixin.NoValue; - } - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ICustomAttributeProvider.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ICustomAttributeProvider.cs deleted file mode 100644 index 89aa552c..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ICustomAttributeProvider.cs +++ /dev/null @@ -1,63 +0,0 @@ -// -// ICustomAttributeProvider.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using Mono.Collections.Generic; - -namespace Mono.Cecil -{ - - public interface ICustomAttributeProvider : IMetadataTokenProvider - { - - Collection CustomAttributes { get; } - - bool HasCustomAttributes { get; } - } - - static partial class Mixin - { - - public static bool GetHasCustomAttributes( - ICustomAttributeProvider self, - ModuleDefinition module) - { - return Mixin.HasImage(module) && module.Read(self, (provider, reader) => reader.HasCustomAttributes(provider)); - } - - public static Collection GetCustomAttributes( - ICustomAttributeProvider self, - ref Collection variable, - ModuleDefinition module) - { - return Mixin.HasImage(module) - ? module.Read(ref variable, self, (provider, reader) => reader.ReadCustomAttributes(provider)) - : variable = new Collection(); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericInstance.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericInstance.cs deleted file mode 100644 index bc90c2bf..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericInstance.cs +++ /dev/null @@ -1,66 +0,0 @@ -// -// IGenericInstance.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Text; - -using Mono.Collections.Generic; - -namespace Mono.Cecil { - - public interface IGenericInstance : IMetadataTokenProvider { - - bool HasGenericArguments { get; } - Collection GenericArguments { get; } - } - - static partial class Mixin { - - public static bool ContainsGenericParameter (IGenericInstance self) - { - var arguments = self.GenericArguments; - - for (int i = 0; i < arguments.Count; i++) - if (arguments [i].ContainsGenericParameter) - return true; - - return false; - } - - public static void GenericInstanceFullName (IGenericInstance self, StringBuilder builder) - { - builder.Append ("<"); - var arguments = self.GenericArguments; - for (int i = 0; i < arguments.Count; i++) { - if (i > 0) - builder.Append (","); - builder.Append (arguments [i].FullName); - } - builder.Append (">"); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericParameterProvider.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericParameterProvider.cs deleted file mode 100644 index 8130174c..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericParameterProvider.cs +++ /dev/null @@ -1,79 +0,0 @@ -// -// IGenericParameterProvider.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - - -using Mono.Collections.Generic; - -namespace Mono.Cecil -{ - - public interface IGenericParameterProvider : IMetadataTokenProvider - { - - bool HasGenericParameters { get; } - bool IsDefinition { get; } - ModuleDefinition Module { get; } - Collection GenericParameters { get; } - GenericParameterType GenericParameterType { get; } - } - - public enum GenericParameterType - { - Type, - Method - } - - interface IGenericContext - { - - bool IsDefinition { get; } - IGenericParameterProvider Type { get; } - IGenericParameterProvider Method { get; } - } - - static partial class Mixin - { - - public static bool GetHasGenericParameters( - IGenericParameterProvider self, - ModuleDefinition module) - { - return Mixin.HasImage(module) && module.Read(self, (provider, reader) => reader.HasGenericParameters(provider)); - } - - public static Collection GetGenericParameters( - IGenericParameterProvider self, - ref Collection collection, - ModuleDefinition module) - { - return Mixin.HasImage(module) - ? module.Read(ref collection, self, (provider, reader) => reader.ReadGenericParameters(provider)) - : collection = new GenericParameterCollection(self); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMarshalInfoProvider.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMarshalInfoProvider.cs deleted file mode 100644 index 369f76b2..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMarshalInfoProvider.cs +++ /dev/null @@ -1,59 +0,0 @@ -// -// IMarshalInfoProvider.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil -{ - - public interface IMarshalInfoProvider : IMetadataTokenProvider - { - - bool HasMarshalInfo { get; } - MarshalInfo MarshalInfo { get; set; } - } - - static partial class Mixin - { - - public static bool GetHasMarshalInfo( - IMarshalInfoProvider self, - ModuleDefinition module) - { - return Mixin.HasImage(module) && module.Read(self, (provider, reader) => reader.HasMarshalInfo(provider)); - } - - public static MarshalInfo GetMarshalInfo( - IMarshalInfoProvider self, - ref MarshalInfo variable, - ModuleDefinition module) - { - return Mixin.HasImage(module) - ? module.Read(ref variable, self, (provider, reader) => reader.ReadMarshalInfo(provider)) - : null; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMemberDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMemberDefinition.cs deleted file mode 100644 index af243162..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMemberDefinition.cs +++ /dev/null @@ -1,105 +0,0 @@ -// -// IMemberDefinition.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil -{ - - public interface IMemberDefinition : ICustomAttributeProvider - { - - string Name { get; set; } - string FullName { get; } - - bool IsSpecialName { get; set; } - bool IsRuntimeSpecialName { get; set; } - - TypeDefinition DeclaringType { get; set; } - } - - static partial class Mixin - { - - public static bool GetAttributes(uint self, uint attributes) - { - return (self & attributes) != 0; - } - - public static uint SetAttributes(uint self, uint attributes, bool value) - { - if (value) - return self | attributes; - - return self & ~attributes; - } - - public static bool GetMaskedAttributes(uint self, uint mask, uint attributes) - { - return (self & mask) == attributes; - } - - public static uint SetMaskedAttributes(uint self, uint mask, uint attributes, bool value) - { - if (value) - { - self &= ~mask; - return self | attributes; - } - - return self & ~(mask & attributes); - } - - public static bool GetAttributes(ushort self, ushort attributes) - { - return (self & attributes) != 0; - } - - public static ushort SetAttributes(ushort self, ushort attributes, bool value) - { - if (value) - return (ushort)(self | attributes); - - return (ushort)(self & ~attributes); - } - - public static bool GetMaskedAttributes(ushort self, ushort mask, uint attributes) - { - return (self & mask) == attributes; - } - - public static ushort SetMaskedAttributes(ushort self, ushort mask, uint attributes, bool value) - { - if (value) - { - self = (ushort)(self & ~mask); - return (ushort)(self | attributes); - } - - return (ushort)(self & ~(mask & attributes)); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataScope.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataScope.cs deleted file mode 100644 index 04a02281..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataScope.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -// IMetadataScope.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public enum MetadataScopeType { - AssemblyNameReference, - ModuleReference, - ModuleDefinition, - } - - public interface IMetadataScope : IMetadataTokenProvider { - MetadataScopeType MetadataScopeType { get; } - string Name { get; set; } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataTokenProvider.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataTokenProvider.cs deleted file mode 100644 index 6621835b..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataTokenProvider.cs +++ /dev/null @@ -1,35 +0,0 @@ -// -// IMetadataTokenProvider.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public interface IMetadataTokenProvider { - - MetadataToken MetadataToken { get; set; } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMethodSignature.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMethodSignature.cs deleted file mode 100644 index 74d285cf..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMethodSignature.cs +++ /dev/null @@ -1,75 +0,0 @@ -// -// IMethodSignature.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Text; - -using Mono.Collections.Generic; - -namespace Mono.Cecil { - - public interface IMethodSignature : IMetadataTokenProvider { - - bool HasThis { get; set; } - bool ExplicitThis { get; set; } - MethodCallingConvention CallingConvention { get; set; } - - bool HasParameters { get; } - Collection Parameters { get; } - TypeReference ReturnType { get; set; } - MethodReturnType MethodReturnType { get; } - } - - static partial class Mixin { - - public static bool HasImplicitThis (IMethodSignature self) - { - return self.HasThis && !self.ExplicitThis; - } - - public static void MethodSignatureFullName (IMethodSignature self, StringBuilder builder) - { - builder.Append ("("); - - if (self.HasParameters) { - var parameters = self.Parameters; - for (int i = 0; i < parameters.Count; i++) { - var parameter = parameters [i]; - if (i > 0) - builder.Append (","); - - if (parameter.ParameterType.IsSentinel) - builder.Append ("...,"); - - builder.Append (parameter.ParameterType.FullName); - } - } - - builder.Append (")"); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/Import.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/Import.cs deleted file mode 100644 index c7b63464..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/Import.cs +++ /dev/null @@ -1,286 +0,0 @@ -// -// Import.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using SR = System.Reflection; - -using Mono.Cecil.Metadata; - -namespace Mono.Cecil -{ - - enum ImportGenericKind - { - Definition, - Open, - } - - class MetadataImporter - { - - readonly ModuleDefinition module; - - public MetadataImporter(ModuleDefinition module) - { - this.module = module; - } - - - public TypeReference ImportType(TypeReference type, IGenericContext context) - { - if (Mixin.IsTypeSpecification(type)) - return ImportTypeSpecification(type, context); - - var reference = new TypeReference( - type.Namespace, - type.Name, - module, - ImportScope(type.Scope), - type.IsValueType); - - MetadataSystem.TryProcessPrimitiveTypeReference(reference); - - if (type.IsNested) - reference.DeclaringType = ImportType(type.DeclaringType, context); - - if (type.HasGenericParameters) - ImportGenericParameters(reference, type); - - return reference; - } - - IMetadataScope ImportScope(IMetadataScope scope) - { - switch (scope.MetadataScopeType) - { - case MetadataScopeType.AssemblyNameReference: - return ImportAssemblyName((AssemblyNameReference)scope); - case MetadataScopeType.ModuleDefinition: - return ImportAssemblyName(((ModuleDefinition)scope).Assembly.Name); - case MetadataScopeType.ModuleReference: - throw new NotImplementedException(); - } - - throw new NotSupportedException(); - } - - AssemblyNameReference ImportAssemblyName(AssemblyNameReference name) - { - AssemblyNameReference reference; - if (TryGetAssemblyNameReference(name, out reference)) - return reference; - - reference = new AssemblyNameReference(name.Name, name.Version) - { - Culture = name.Culture, - HashAlgorithm = name.HashAlgorithm, - }; - - var pk_token = !Mixin.IsNullOrEmpty(name.PublicKeyToken) - ? new byte[name.PublicKeyToken.Length] - : Empty.Array; - - if (pk_token.Length > 0) - Buffer.BlockCopy(name.PublicKeyToken, 0, pk_token, 0, pk_token.Length); - - reference.PublicKeyToken = pk_token; - - module.AssemblyReferences.Add(reference); - - return reference; - } - - bool TryGetAssemblyNameReference(AssemblyNameReference name_reference, out AssemblyNameReference assembly_reference) - { - var references = module.AssemblyReferences; - - for (int i = 0; i < references.Count; i++) - { - var reference = references[i]; - if (name_reference.FullName != reference.FullName) // TODO compare field by field - continue; - - assembly_reference = reference; - return true; - } - - assembly_reference = null; - return false; - } - - static void ImportGenericParameters(IGenericParameterProvider imported, IGenericParameterProvider original) - { - var parameters = original.GenericParameters; - var imported_parameters = imported.GenericParameters; - - for (int i = 0; i < parameters.Count; i++) - imported_parameters.Add(new GenericParameter(parameters[i].Name, imported)); - } - - TypeReference ImportTypeSpecification(TypeReference type, IGenericContext context) - { - switch (type.etype) - { - case ElementType.SzArray: - var vector = (ArrayType)type; - return new ArrayType(ImportType(vector.ElementType, context)); - case ElementType.Ptr: - var pointer = (PointerType)type; - return new PointerType(ImportType(pointer.ElementType, context)); - case ElementType.ByRef: - var byref = (ByReferenceType)type; - return new ByReferenceType(ImportType(byref.ElementType, context)); - case ElementType.Pinned: - var pinned = (PinnedType)type; - return new PinnedType(ImportType(pinned.ElementType, context)); - case ElementType.Sentinel: - var sentinel = (SentinelType)type; - return new SentinelType(ImportType(sentinel.ElementType, context)); - case ElementType.CModOpt: - var modopt = (OptionalModifierType)type; - return new OptionalModifierType( - ImportType(modopt.ModifierType, context), - ImportType(modopt.ElementType, context)); - case ElementType.CModReqD: - var modreq = (RequiredModifierType)type; - return new RequiredModifierType( - ImportType(modreq.ModifierType, context), - ImportType(modreq.ElementType, context)); - case ElementType.Array: - var array = (ArrayType)type; - var imported_array = new ArrayType(ImportType(array.ElementType, context)); - if (array.IsVector) - return imported_array; - - var dimensions = array.Dimensions; - var imported_dimensions = imported_array.Dimensions; - - imported_dimensions.Clear(); - - for (int i = 0; i < dimensions.Count; i++) - { - var dimension = dimensions[i]; - - imported_dimensions.Add(new ArrayDimension(dimension.LowerBound, dimension.UpperBound)); - } - - return imported_array; - case ElementType.GenericInst: - var instance = (GenericInstanceType)type; - var element_type = ImportType(instance.ElementType, context); - var imported_instance = new GenericInstanceType(element_type); - - var arguments = instance.GenericArguments; - var imported_arguments = imported_instance.GenericArguments; - - for (int i = 0; i < arguments.Count; i++) - imported_arguments.Add(ImportType(arguments[i], context)); - - return imported_instance; - case ElementType.Var: - if (context == null || context.Type == null) - throw new InvalidOperationException(); - - return ((TypeReference)context.Type).GetElementType().GenericParameters[((GenericParameter)type).Position]; - case ElementType.MVar: - if (context == null || context.Method == null) - throw new InvalidOperationException(); - - return context.Method.GenericParameters[((GenericParameter)type).Position]; - } - - throw new NotSupportedException(type.etype.ToString()); - } - - public FieldReference ImportField(FieldReference field, IGenericContext context) - { - var declaring_type = ImportType(field.DeclaringType, context); - - return new FieldReference - { - Name = field.Name, - DeclaringType = declaring_type, - FieldType = ImportType(field.FieldType, context ?? declaring_type), - }; - } - - public MethodReference ImportMethod(MethodReference method, IGenericContext context) - { - if (method.IsGenericInstance) - return ImportMethodSpecification(method, context); - - var declaring_type = ImportType(method.DeclaringType, context); - - var reference = new MethodReference - { - Name = method.Name, - HasThis = method.HasThis, - ExplicitThis = method.ExplicitThis, - DeclaringType = declaring_type, - }; - - reference.CallingConvention = method.CallingConvention; - - if (method.HasGenericParameters) - ImportGenericParameters(reference, method); - - reference.ReturnType = ImportType(method.ReturnType, context ?? reference); - - if (!method.HasParameters) - return reference; - - var reference_parameters = reference.Parameters; - - var parameters = method.Parameters; - for (int i = 0; i < parameters.Count; i++) - reference_parameters.Add( - new ParameterDefinition(ImportType(parameters[i].ParameterType, context ?? reference))); - - return reference; - } - - MethodSpecification ImportMethodSpecification(MethodReference method, IGenericContext context) - { - if (!method.IsGenericInstance) - throw new NotSupportedException(); - - var instance = (GenericInstanceMethod)method; - var element_method = ImportMethod(instance.ElementMethod, context); - var imported_instance = new GenericInstanceMethod(element_method); - - var arguments = instance.GenericArguments; - var imported_arguments = imported_instance.GenericArguments; - - for (int i = 0; i < arguments.Count; i++) - imported_arguments.Add(ImportType(arguments[i], context)); - - return imported_instance; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/LinkedResource.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/LinkedResource.cs deleted file mode 100644 index 16c1d59b..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/LinkedResource.cs +++ /dev/null @@ -1,60 +0,0 @@ -// -// LinkedResource.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public sealed class LinkedResource : Resource { - - internal byte [] hash; - string file; - - public byte [] Hash { - get { return hash; } - } - - public string File { - get { return file; } - set { file = value; } - } - - public override ResourceType ResourceType { - get { return ResourceType.Linked; } - } - - public LinkedResource (string name, ManifestResourceAttributes flags) - : base (name, flags) - { - } - - public LinkedResource (string name, ManifestResourceAttributes flags, string file) - : base (name, flags) - { - this.file = file; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ManifestResourceAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ManifestResourceAttributes.cs deleted file mode 100644 index 7d6bb190..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ManifestResourceAttributes.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// ManifestResourceAttributes.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - [Flags] - public enum ManifestResourceAttributes : uint { - VisibilityMask = 0x0007, - Public = 0x0001, // The resource is exported from the Assembly - Private = 0x0002 // The resource is private to the Assembly - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberDefinitionCollection.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberDefinitionCollection.cs deleted file mode 100644 index 707f36fb..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberDefinitionCollection.cs +++ /dev/null @@ -1,92 +0,0 @@ -// -// MemberDefinitionCollection.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using Mono.Collections.Generic; - -namespace Mono.Cecil { - - class MemberDefinitionCollection : Collection where T : IMemberDefinition { - - TypeDefinition container; - - internal MemberDefinitionCollection (TypeDefinition container) - { - this.container = container; - } - - internal MemberDefinitionCollection (TypeDefinition container, int capacity) - : base (capacity) - { - this.container = container; - } - - protected override void OnAdd (T item, int index) - { - Attach (item); - } - - protected sealed override void OnSet (T item, int index) - { - Attach (item); - } - - protected sealed override void OnInsert (T item, int index) - { - Attach (item); - } - - protected sealed override void OnRemove (T item, int index) - { - Detach (item); - } - - protected sealed override void OnClear () - { - foreach (var definition in this) - Detach (definition); - } - - void Attach (T element) - { - if (element.DeclaringType == container) - return; - - if (element.DeclaringType != null) - throw new ArgumentException ("Member already attached"); - - element.DeclaringType = this.container; - } - - static void Detach (T element) - { - element.DeclaringType = null; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataResolver.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataResolver.cs deleted file mode 100644 index fca42fa6..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataResolver.cs +++ /dev/null @@ -1,370 +0,0 @@ -// -// MetadataResolver.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using Mono.Collections.Generic; - -namespace Mono.Cecil -{ - - public interface IAssemblyResolver - { - AssemblyDefinition Resolve(AssemblyNameReference name); - AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters); - - AssemblyDefinition Resolve(string fullName); - AssemblyDefinition Resolve(string fullName, ReaderParameters parameters); - event AssemblyResolveEventHandler ResolveFailure; - } - - public interface IMetadataResolver - { - TypeDefinition Resolve(TypeReference type); - FieldDefinition Resolve(FieldReference field); - MethodDefinition Resolve(MethodReference method); - } - - - public class ResolutionException : Exception - { - - readonly MemberReference member; - - public MemberReference Member - { - get { return member; } - } - - public ResolutionException(MemberReference member) - : base("Failed to resolve " + member.FullName) - { - this.member = member; - } - - - } - - public class MetadataResolver : IMetadataResolver - { - - readonly IAssemblyResolver assembly_resolver; - - public IAssemblyResolver AssemblyResolver - { - get { return assembly_resolver; } - } - - public MetadataResolver(IAssemblyResolver assemblyResolver) - { - if (assemblyResolver == null) - throw new ArgumentNullException("assemblyResolver"); - - assembly_resolver = assemblyResolver; - } - - public virtual TypeDefinition Resolve(TypeReference type) - { - if (type == null) - throw new ArgumentNullException("type"); - - type = type.GetElementType(); - - var scope = type.Scope; - switch (scope.MetadataScopeType) - { - case MetadataScopeType.AssemblyNameReference: - var assembly = assembly_resolver.Resolve((AssemblyNameReference)scope); - if (assembly == null) - return null; - - return GetType(assembly.MainModule, type); - case MetadataScopeType.ModuleDefinition: - return GetType((ModuleDefinition)scope, type); - case MetadataScopeType.ModuleReference: - var modules = type.Module.Assembly.Modules; - var module_ref = (ModuleReference)scope; - for (int i = 0; i < modules.Count; i++) - { - var netmodule = modules[i]; - if (netmodule.Name == module_ref.Name) - return GetType(netmodule, type); - } - break; - } - - throw new NotSupportedException(); - } - - static TypeDefinition GetType(ModuleDefinition module, TypeReference reference) - { - var type = GetTypeDefinition(module, reference); - if (type != null) - return type; - - if (!module.HasExportedTypes) - return null; - - var exported_types = module.ExportedTypes; - - for (int i = 0; i < exported_types.Count; i++) - { - var exported_type = exported_types[i]; - if (exported_type.Name != reference.Name) - continue; - - if (exported_type.Namespace != reference.Namespace) - continue; - - return exported_type.Resolve(); - } - - return null; - } - - static TypeDefinition GetTypeDefinition(ModuleDefinition module, TypeReference type) - { - if (!type.IsNested) - return module.GetType(type.Namespace, type.Name); - - var declaring_type = type.DeclaringType.Resolve(); - if (declaring_type == null) - return null; - - return Mixin.GetNestedType(declaring_type, type.Name); - } - - public virtual FieldDefinition Resolve(FieldReference field) - { - if (field == null) - throw new ArgumentNullException("field"); - - var type = Resolve(field.DeclaringType); - if (type == null) - return null; - - if (!type.HasFields) - return null; - - return GetField(type, field); - } - - FieldDefinition GetField(TypeDefinition type, FieldReference reference) - { - while (type != null) - { - var field = GetField(type.Fields, reference); - if (field != null) - return field; - - if (type.BaseType == null) - return null; - - type = Resolve(type.BaseType); - } - - return null; - } - - static FieldDefinition GetField(Collection fields, FieldReference reference) - { - for (int i = 0; i < fields.Count; i++) - { - var field = fields[i]; - - if (field.Name != reference.Name) - continue; - - if (!AreSame(field.FieldType, reference.FieldType)) - continue; - - return field; - } - - return null; - } - - public virtual MethodDefinition Resolve(MethodReference method) - { - if (method == null) - throw new ArgumentNullException("method"); - - var type = Resolve(method.DeclaringType); - if (type == null) - return null; - - method = method.GetElementMethod(); - - if (!type.HasMethods) - return null; - - return GetMethod(type, method); - } - - MethodDefinition GetMethod(TypeDefinition type, MethodReference reference) - { - while (type != null) - { - var method = GetMethod(type.Methods, reference); - if (method != null) - return method; - - if (type.BaseType == null) - return null; - - type = Resolve(type.BaseType); - } - - return null; - } - - public static MethodDefinition GetMethod(Collection methods, MethodReference reference) - { - for (int i = 0; i < methods.Count; i++) - { - var method = methods[i]; - - if (method.Name != reference.Name) - continue; - - if (method.HasGenericParameters != reference.HasGenericParameters) - continue; - - if (method.HasGenericParameters && method.GenericParameters.Count != reference.GenericParameters.Count) - continue; - - if (!AreSame(method.ReturnType, reference.ReturnType)) - continue; - - if (method.HasParameters != reference.HasParameters) - continue; - - if (!method.HasParameters && !reference.HasParameters) - return method; - - if (!AreSame(method.Parameters, reference.Parameters)) - continue; - - return method; - } - - return null; - } - - static bool AreSame(Collection a, Collection b) - { - var count = a.Count; - - if (count != b.Count) - return false; - - if (count == 0) - return true; - - for (int i = 0; i < count; i++) - if (!AreSame(a[i].ParameterType, b[i].ParameterType)) - return false; - - return true; - } - - static bool AreSame(TypeSpecification a, TypeSpecification b) - { - if (!AreSame(a.ElementType, b.ElementType)) - return false; - - if (a.IsGenericInstance) - return AreSame((GenericInstanceType)a, (GenericInstanceType)b); - - if (a.IsRequiredModifier || a.IsOptionalModifier) - return AreSame((IModifierType)a, (IModifierType)b); - - if (a.IsArray) - return AreSame((ArrayType)a, (ArrayType)b); - - return true; - } - - static bool AreSame(ArrayType a, ArrayType b) - { - if (a.Rank != b.Rank) - return false; - - // TODO: dimensions - - return true; - } - - static bool AreSame(IModifierType a, IModifierType b) - { - return AreSame(a.ModifierType, b.ModifierType); - } - - static bool AreSame(GenericInstanceType a, GenericInstanceType b) - { - if (a.GenericArguments.Count != b.GenericArguments.Count) - return false; - - for (int i = 0; i < a.GenericArguments.Count; i++) - if (!AreSame(a.GenericArguments[i], b.GenericArguments[i])) - return false; - - return true; - } - - static bool AreSame(GenericParameter a, GenericParameter b) - { - return a.Position == b.Position; - } - - static bool AreSame(TypeReference a, TypeReference b) - { - if (ReferenceEquals(a, b)) - return true; - - if (a == null || b == null) - return false; - - if (a.etype != b.etype) - return false; - - if (a.IsGenericParameter) - return AreSame((GenericParameter)a, (GenericParameter)b); - - if (Mixin.IsTypeSpecification(a)) - return AreSame((TypeSpecification)a, (TypeSpecification)b); - - if (a.Name != b.Name || a.Namespace != b.Namespace) - return false; - - //TODO: check scope - - return AreSame(a.DeclaringType, b.DeclaringType); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodCallingConvention.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodCallingConvention.cs deleted file mode 100644 index bd7188db..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodCallingConvention.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// MethodCallingConvention.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public enum MethodCallingConvention : byte { - Default = 0x0, - C = 0x1, - StdCall = 0x2, - ThisCall = 0x3, - FastCall = 0x4, - VarArg = 0x5, - Generic = 0x10, - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodDefinition.cs deleted file mode 100644 index c34cd083..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodDefinition.cs +++ /dev/null @@ -1,570 +0,0 @@ -// -// MethodDefinition.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using Mono.Cecil.Cil; -using Mono.Collections.Generic; - -using RVA = System.UInt32; - -namespace Mono.Cecil -{ - - public sealed class MethodDefinition : MethodReference, IMemberDefinition, ISecurityDeclarationProvider - { - - ushort attributes; - ushort impl_attributes; - internal volatile bool sem_attrs_ready; - internal MethodSemanticsAttributes sem_attrs; - Collection custom_attributes; - Collection security_declarations; - - internal RVA rva; - internal PInvokeInfo pinvoke; - Collection overrides; - - internal MethodBody body; - - public MethodAttributes Attributes - { - get { return (MethodAttributes)attributes; } - set { attributes = (ushort)value; } - } - - public MethodImplAttributes ImplAttributes - { - get { return (MethodImplAttributes)impl_attributes; } - set { impl_attributes = (ushort)value; } - } - - public MethodSemanticsAttributes SemanticsAttributes - { - get - { - if (sem_attrs_ready) - return sem_attrs; - - if (HasImage) - { - ReadSemantics(); - return sem_attrs; - } - - sem_attrs = MethodSemanticsAttributes.None; - sem_attrs_ready = true; - return sem_attrs; - } - set { sem_attrs = value; } - } - - internal void ReadSemantics() - { - if (sem_attrs_ready) - return; - - var module = this.Module; - if (module == null) - return; - - if (!module.HasImage) - return; - - module.Read(this, (method, reader) => reader.ReadAllSemantics(method)); - } - - public bool HasSecurityDeclarations - { - get - { - if (security_declarations != null) - return security_declarations.Count > 0; - - return Mixin.GetHasSecurityDeclarations(this, Module); - } - } - - public Collection SecurityDeclarations - { - get { return security_declarations ?? (Mixin.GetSecurityDeclarations(this, ref security_declarations, Module)); } - } - - public bool HasCustomAttributes - { - get - { - if (custom_attributes != null) - return custom_attributes.Count > 0; - - return Mixin.GetHasCustomAttributes(this, Module); - } - } - - public Collection CustomAttributes - { - get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } - } - - public int RVA - { - get { return (int)rva; } - } - - public bool HasBody - { - get - { - return (attributes & (ushort)MethodAttributes.Abstract) == 0 && - (attributes & (ushort)MethodAttributes.PInvokeImpl) == 0 && - (impl_attributes & (ushort)MethodImplAttributes.InternalCall) == 0 && - (impl_attributes & (ushort)MethodImplAttributes.Native) == 0 && - (impl_attributes & (ushort)MethodImplAttributes.Unmanaged) == 0 && - (impl_attributes & (ushort)MethodImplAttributes.Runtime) == 0; - } - } - - public MethodBody Body - { - get - { - MethodBody localBody = this.body; - if (localBody != null) - return localBody; - - if (!HasBody) - return null; - - if (HasImage && rva != 0) - return Module.Read(ref body, this, (method, reader) => reader.ReadMethodBody(method)); - - return body = new MethodBody(this); - } - set - { - // we reset Body to null in ILSpy to save memory; so we need that operation to be thread-safe - lock (Module.SyncRoot) - { - body = value; - } - } - } - - public bool HasPInvokeInfo - { - get - { - if (pinvoke != null) - return true; - - return IsPInvokeImpl; - } - } - - public PInvokeInfo PInvokeInfo - { - get - { - if (pinvoke != null) - return pinvoke; - - if (HasImage && IsPInvokeImpl) - return Module.Read(ref pinvoke, this, (method, reader) => reader.ReadPInvokeInfo(method)); - - return null; - } - set - { - IsPInvokeImpl = true; - pinvoke = value; - } - } - - public bool HasOverrides - { - get - { - if (overrides != null) - return overrides.Count > 0; - - if (HasImage) - return Module.Read(this, (method, reader) => reader.HasOverrides(method)); - - return false; - } - } - - public Collection Overrides - { - get - { - if (overrides != null) - return overrides; - - if (HasImage) - return Module.Read(ref overrides, this, (method, reader) => reader.ReadOverrides(method)); - - return overrides = new Collection(); - } - } - - public override bool HasGenericParameters - { - get - { - if (generic_parameters != null) - return generic_parameters.Count > 0; - - return Mixin.GetHasGenericParameters(this, Module); - } - } - - public override Collection GenericParameters - { - get { return generic_parameters ?? (Mixin.GetGenericParameters(this, ref generic_parameters, Module)); } - } - - #region MethodAttributes - - public bool IsCompilerControlled - { - get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.CompilerControlled); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.CompilerControlled, value); } - } - - public bool IsPrivate - { - get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Private); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Private, value); } - } - - public bool IsFamilyAndAssembly - { - get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.FamANDAssem); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.FamANDAssem, value); } - } - - public bool IsAssembly - { - get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Assembly); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Assembly, value); } - } - - public bool IsFamily - { - get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Family); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Family, value); } - } - - public bool IsFamilyOrAssembly - { - get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.FamORAssem); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.FamORAssem, value); } - } - - public bool IsPublic - { - get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Public); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Public, value); } - } - - public bool IsStatic - { - get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.Static); } - set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.Static, value); } - } - - public bool IsFinal - { - get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.Final); } - set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.Final, value); } - } - - public bool IsVirtual - { - get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.Virtual); } - set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.Virtual, value); } - } - - public bool IsHideBySig - { - get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.HideBySig); } - set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.HideBySig, value); } - } - - public bool IsReuseSlot - { - get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.VtableLayoutMask, (ushort)MethodAttributes.ReuseSlot); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.VtableLayoutMask, (ushort)MethodAttributes.ReuseSlot, value); } - } - - public bool IsNewSlot - { - get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.VtableLayoutMask, (ushort)MethodAttributes.NewSlot); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.VtableLayoutMask, (ushort)MethodAttributes.NewSlot, value); } - } - - public bool IsCheckAccessOnOverride - { - get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.CheckAccessOnOverride); } - set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.CheckAccessOnOverride, value); } - } - - public bool IsAbstract - { - get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.Abstract); } - set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.Abstract, value); } - } - - public bool IsSpecialName - { - get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.SpecialName); } - set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.SpecialName, value); } - } - - public bool IsPInvokeImpl - { - get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.PInvokeImpl); } - set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.PInvokeImpl, value); } - } - - public bool IsUnmanagedExport - { - get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.UnmanagedExport); } - set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.UnmanagedExport, value); } - } - - public bool IsRuntimeSpecialName - { - get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.RTSpecialName); } - set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.RTSpecialName, value); } - } - - public bool HasSecurity - { - get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.HasSecurity); } - set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.HasSecurity, value); } - } - - #endregion - - #region MethodImplAttributes - - public bool IsIL - { - get { return Mixin.GetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.IL); } - set { impl_attributes = Mixin.SetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.IL, value); } - } - - public bool IsNative - { - get { return Mixin.GetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.Native); } - set { impl_attributes = Mixin.SetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.Native, value); } - } - - public bool IsRuntime - { - get { return Mixin.GetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.Runtime); } - set { impl_attributes = Mixin.SetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.Runtime, value); } - } - - public bool IsUnmanaged - { - get { return Mixin.GetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.ManagedMask, (ushort)MethodImplAttributes.Unmanaged); } - set { impl_attributes = Mixin.SetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.ManagedMask, (ushort)MethodImplAttributes.Unmanaged, value); } - } - - public bool IsManaged - { - get { return Mixin.GetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.ManagedMask, (ushort)MethodImplAttributes.Managed); } - set { impl_attributes = Mixin.SetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.ManagedMask, (ushort)MethodImplAttributes.Managed, value); } - } - - public bool IsForwardRef - { - get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.ForwardRef); } - set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.ForwardRef, value); } - } - - public bool IsPreserveSig - { - get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.PreserveSig); } - set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.PreserveSig, value); } - } - - public bool IsInternalCall - { - get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.InternalCall); } - set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.InternalCall, value); } - } - - public bool IsSynchronized - { - get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.Synchronized); } - set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.Synchronized, value); } - } - - public bool NoInlining - { - get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.NoInlining); } - set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.NoInlining, value); } - } - - public bool NoOptimization - { - get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.NoOptimization); } - set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.NoOptimization, value); } - } - - #endregion - - #region MethodSemanticsAttributes - - public bool IsSetter - { - get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.Setter); } - set { Mixin.SetSemantics(this, MethodSemanticsAttributes.Setter, value); } - } - - public bool IsGetter - { - get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.Getter); } - set { Mixin.SetSemantics(this, MethodSemanticsAttributes.Getter, value); } - } - - public bool IsOther - { - get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.Other); } - set { Mixin.SetSemantics(this, MethodSemanticsAttributes.Other, value); } - } - - public bool IsAddOn - { - get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.AddOn); } - set { Mixin.SetSemantics(this, MethodSemanticsAttributes.AddOn, value); } - } - - public bool IsRemoveOn - { - get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.RemoveOn); } - set { Mixin.SetSemantics(this, MethodSemanticsAttributes.RemoveOn, value); } - } - - public bool IsFire - { - get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.Fire); } - set { Mixin.SetSemantics(this, MethodSemanticsAttributes.Fire, value); } - } - - #endregion - - public new TypeDefinition DeclaringType - { - get { return (TypeDefinition)base.DeclaringType; } - set { base.DeclaringType = value; } - } - - public bool IsConstructor - { - get - { - return this.IsRuntimeSpecialName - && this.IsSpecialName - && (this.Name == ".cctor" || this.Name == ".ctor"); - } - } - - public override bool IsDefinition - { - get { return true; } - } - - internal MethodDefinition() - { - this.token = new MetadataToken(TokenType.Method); - } - - public MethodDefinition(string name, MethodAttributes attributes, TypeReference returnType) - : base(name, returnType) - { - this.attributes = (ushort)attributes; - this.HasThis = !this.IsStatic; - this.token = new MetadataToken(TokenType.Method); - } - - public override MethodDefinition Resolve() - { - return this; - } - } - - static partial class Mixin - { - - public static ParameterDefinition GetParameter(MethodBody self, int index) - { - var method = self.method; - - if (method.HasThis) - { - if (index == 0) - return self.ThisParameter; - - index--; - } - - var parameters = method.Parameters; - - if (index < 0 || index >= parameters.size) - return null; - - return parameters[index]; - } - - public static VariableDefinition GetVariable(MethodBody self, int index) - { - var variables = self.Variables; - - if (index < 0 || index >= variables.size) - return null; - - return variables[index]; - } - - public static bool GetSemantics(MethodDefinition self, MethodSemanticsAttributes semantics) - { - return (self.SemanticsAttributes & semantics) != 0; - } - - public static void SetSemantics(MethodDefinition self, MethodSemanticsAttributes semantics, bool value) - { - if (value) - self.SemanticsAttributes |= semantics; - else - self.SemanticsAttributes &= ~semantics; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodImplAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodImplAttributes.cs deleted file mode 100644 index b24fcf70..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodImplAttributes.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -// MethodImplAttributes.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - [Flags] - public enum MethodImplAttributes : ushort { - CodeTypeMask = 0x0003, - IL = 0x0000, // Method impl is CIL - Native = 0x0001, // Method impl is native - OPTIL = 0x0002, // Reserved: shall be zero in conforming implementations - Runtime = 0x0003, // Method impl is provided by the runtime - - ManagedMask = 0x0004, // Flags specifying whether the code is managed or unmanaged - Unmanaged = 0x0004, // Method impl is unmanaged, otherwise managed - Managed = 0x0000, // Method impl is managed - - // Implementation info and interop - ForwardRef = 0x0010, // Indicates method is defined; used primarily in merge scenarios - PreserveSig = 0x0080, // Reserved: conforming implementations may ignore - InternalCall = 0x1000, // Reserved: shall be zero in conforming implementations - Synchronized = 0x0020, // Method is single threaded through the body - NoOptimization = 0x0040, // Method is not optimized by the JIT. - NoInlining = 0x0008, // Method may not be inlined - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReference.cs deleted file mode 100644 index 371b94a8..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReference.cs +++ /dev/null @@ -1,247 +0,0 @@ -// -// MethodReference.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Text; - -using Mono.Collections.Generic; - -namespace Mono.Cecil -{ - - public class MethodReference : MemberReference, IMethodSignature, IGenericParameterProvider, IGenericContext - { - int hashCode = -1; - static int instance_id; - internal ParameterDefinitionCollection parameters; - MethodReturnType return_type; - - bool has_this; - bool explicit_this; - MethodCallingConvention calling_convention; - internal Collection generic_parameters; - - public virtual bool HasThis - { - get { return has_this; } - set { has_this = value; } - } - - public virtual bool ExplicitThis - { - get { return explicit_this; } - set { explicit_this = value; } - } - - public virtual MethodCallingConvention CallingConvention - { - get { return calling_convention; } - set { calling_convention = value; } - } - - public virtual bool HasParameters - { - get { return !Mixin.IsNullOrEmpty(parameters); } - } - - public virtual Collection Parameters - { - get - { - if (parameters == null) - parameters = new ParameterDefinitionCollection(this); - - return parameters; - } - } - - IGenericParameterProvider IGenericContext.Type - { - get - { - var declaring_type = this.DeclaringType; - var instance = declaring_type as GenericInstanceType; - if (instance != null) - return instance.ElementType; - - return declaring_type; - } - } - - IGenericParameterProvider IGenericContext.Method - { - get { return this; } - } - - GenericParameterType IGenericParameterProvider.GenericParameterType - { - get { return GenericParameterType.Method; } - } - - public virtual bool HasGenericParameters - { - get { return !Mixin.IsNullOrEmpty(generic_parameters); } - } - - public virtual Collection GenericParameters - { - get - { - if (generic_parameters != null) - return generic_parameters; - - return generic_parameters = new GenericParameterCollection(this); - } - } - - public TypeReference ReturnType - { - get - { - var return_type = MethodReturnType; - return return_type != null ? return_type.ReturnType : null; - } - set - { - var return_type = MethodReturnType; - if (return_type != null) - return_type.ReturnType = value; - } - } - - public virtual MethodReturnType MethodReturnType - { - get { return return_type; } - set { return_type = value; } - } - - public override string FullName - { - get - { - var builder = new StringBuilder(); - builder.Append(ReturnType.FullName) - .Append(" ") - .Append(MemberFullName()); - Mixin.MethodSignatureFullName(this, builder); - return builder.ToString(); - } - } - - public override int GetHashCode() - { - if (hashCode == -1) - hashCode = System.Threading.Interlocked.Add(ref instance_id, 1); - return hashCode; - } - - public virtual bool IsGenericInstance - { - get { return false; } - } - - internal override bool ContainsGenericParameter - { - get - { - if (this.ReturnType.ContainsGenericParameter || base.ContainsGenericParameter) - return true; - - var parameters = this.Parameters; - - for (int i = 0; i < parameters.Count; i++) - if (parameters[i].ParameterType.ContainsGenericParameter) - return true; - - return false; - } - } - - internal MethodReference() - { - this.return_type = new MethodReturnType(this); - this.token = new MetadataToken(TokenType.MemberRef); - } - - public MethodReference(string name, TypeReference returnType) - : base(name) - { - if (returnType == null) - throw new ArgumentNullException("returnType"); - - this.return_type = new MethodReturnType(this); - this.return_type.ReturnType = returnType; - this.token = new MetadataToken(TokenType.MemberRef); - } - - public MethodReference(string name, TypeReference returnType, TypeReference declaringType) - : this(name, returnType) - { - if (declaringType == null) - throw new ArgumentNullException("declaringType"); - - this.DeclaringType = declaringType; - } - - public virtual MethodReference GetElementMethod() - { - return this; - } - - public virtual MethodDefinition Resolve() - { - var module = this.Module; - if (module == null) - throw new NotSupportedException(); - - return module.Resolve(this); - } - } - - static partial class Mixin - { - - public static bool IsVarArg(IMethodSignature self) - { - return (self.CallingConvention & MethodCallingConvention.VarArg) != 0; - } - - public static int GetSentinelPosition(IMethodSignature self) - { - if (!self.HasParameters) - return -1; - - var parameters = self.Parameters; - for (int i = 0; i < parameters.Count; i++) - if (parameters[i].ParameterType.IsSentinel) - return i; - - return -1; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSemanticsAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSemanticsAttributes.cs deleted file mode 100644 index dd0f4742..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSemanticsAttributes.cs +++ /dev/null @@ -1,43 +0,0 @@ -// -// MethodSemanticsattributes.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - [Flags] - public enum MethodSemanticsAttributes : ushort { - None = 0x0000, - Setter = 0x0001, // Setter for property - Getter = 0x0002, // Getter for property - Other = 0x0004, // Other method for property or event - AddOn = 0x0008, // AddOn method for event - RemoveOn = 0x0010, // RemoveOn method for event - Fire = 0x0020 // Fire method for event - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleDefinition.cs deleted file mode 100644 index 979d8f9f..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleDefinition.cs +++ /dev/null @@ -1,755 +0,0 @@ -// -// ModuleDefinition.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading; -using SR = System.Reflection; -using Mono.Cecil.Cil; -using Mono.Cecil.Metadata; -using Mono.Cecil.PE; -using Mono.Collections.Generic; - -namespace Mono.Cecil -{ - - public enum ReadingMode - { - Immediate = 1, - Deferred = 2, - } - - public sealed class ReaderParameters - { - - ReadingMode reading_mode; - IAssemblyResolver assembly_resolver; - IMetadataResolver metadata_resolver; - Stream symbol_stream; - ISymbolReaderProvider symbol_reader_provider; - bool read_symbols; - - public ReadingMode ReadingMode - { - get { return reading_mode; } - set { reading_mode = value; } - } - - public IAssemblyResolver AssemblyResolver - { - get { return assembly_resolver; } - set { assembly_resolver = value; } - } - - public IMetadataResolver MetadataResolver - { - get { return metadata_resolver; } - set { metadata_resolver = value; } - } - - public Stream SymbolStream - { - get { return symbol_stream; } - set { symbol_stream = value; } - } - - public ISymbolReaderProvider SymbolReaderProvider - { - get { return symbol_reader_provider; } - set { symbol_reader_provider = value; } - } - - public bool ReadSymbols - { - get { return read_symbols; } - set { read_symbols = value; } - } - - public ReaderParameters() - : this(ReadingMode.Deferred) - { - } - - public ReaderParameters(ReadingMode readingMode) - { - this.reading_mode = readingMode; - } - } - - - public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider - { - - internal Image Image; - internal MetadataSystem MetadataSystem; - internal ReadingMode ReadingMode; - internal ISymbolReaderProvider SymbolReaderProvider; - - internal ISymbolReader symbol_reader; - internal IAssemblyResolver assembly_resolver; - internal IMetadataResolver metadata_resolver; - internal TypeSystem type_system; - - readonly MetadataReader reader; - readonly string fq_name; - - internal ModuleKind kind; - TargetRuntime runtime; - TargetArchitecture architecture; - ModuleAttributes attributes; - ModuleCharacteristics characteristics; - Guid mvid; - - internal AssemblyDefinition assembly; - MethodDefinition entry_point; - - Collection custom_attributes; - Collection references; - Collection modules; - Collection resources; - Collection exported_types; - TypeDefinitionCollection types; - - public bool IsMain - { - get { return kind != ModuleKind.NetModule; } - } - - public ModuleKind Kind - { - get { return kind; } - set { kind = value; } - } - - public TargetRuntime Runtime - { - get { return runtime; } - set { runtime = value; } - } - - public TargetArchitecture Architecture - { - get { return architecture; } - set { architecture = value; } - } - - public ModuleAttributes Attributes - { - get { return attributes; } - set { attributes = value; } - } - - public ModuleCharacteristics Characteristics - { - get { return characteristics; } - set { characteristics = value; } - } - - public string FullyQualifiedName - { - get { return fq_name; } - } - - public Guid Mvid - { - get { return mvid; } - set { mvid = value; } - } - - internal bool HasImage - { - get { return Image != null; } - } - - public bool HasSymbols - { - get { return symbol_reader != null; } - } - - public ISymbolReader SymbolReader - { - get { return symbol_reader; } - } - - public override MetadataScopeType MetadataScopeType - { - get { return MetadataScopeType.ModuleDefinition; } - } - - public AssemblyDefinition Assembly - { - get { return assembly; } - } - - - public IAssemblyResolver AssemblyResolver - { - get { return assembly_resolver ?? (assembly_resolver = new DefaultAssemblyResolver()); } - } - - public IMetadataResolver MetadataResolver - { - get - { - if (metadata_resolver == null) - metadata_resolver=new MetadataResolver(this.AssemblyResolver); - - return metadata_resolver; - } - } - - public TypeSystem TypeSystem - { - get - { - if (type_system == null) - type_system = TypeSystem.CreateTypeSystem(this); - return type_system; - } - } - - public bool HasAssemblyReferences - { - get - { - if (references != null) - return references.Count > 0; - - return HasImage && Image.HasTable(Table.AssemblyRef); - } - } - - public Collection AssemblyReferences - { - get - { - if (references != null) - return references; - - if (HasImage) - return Read(ref references, this, (_, reader) => reader.ReadAssemblyReferences()); - - return references = new Collection(); - } - } - - public bool HasModuleReferences - { - get - { - if (modules != null) - return modules.Count > 0; - - return HasImage && Image.HasTable(Table.ModuleRef); - } - } - - public Collection ModuleReferences - { - get - { - if (modules != null) - return modules; - - if (HasImage) - return Read(ref modules, this, (_, reader) => reader.ReadModuleReferences()); - - return modules = new Collection(); - } - } - - public bool HasResources - { - get - { - if (resources != null) - return resources.Count > 0; - - if (HasImage) - return Image.HasTable(Table.ManifestResource) || Read(this, (_, reader) => reader.HasFileResource()); - - return false; - } - } - - public Collection Resources - { - get - { - if (resources != null) - return resources; - - if (HasImage) - return Read(ref resources, this, (_, reader) => reader.ReadResources()); - - return resources = new Collection(); - } - } - - public bool HasCustomAttributes - { - get - { - if (custom_attributes != null) - return custom_attributes.Count > 0; - - return Mixin.GetHasCustomAttributes(this, this); - } - } - - public Collection CustomAttributes - { - get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, this)); } - } - - public bool HasTypes - { - get - { - if (types != null) - return types.Count > 0; - - return HasImage && Image.HasTable(Table.TypeDef); - } - } - - public Collection Types - { - get - { - if (types != null) - return types; - - if (HasImage) - return Read(ref types, this, (_, reader) => reader.ReadTypes()); - - return types = new TypeDefinitionCollection(this); - } - } - - public bool HasExportedTypes - { - get - { - if (exported_types != null) - return exported_types.Count > 0; - - return HasImage && Image.HasTable(Table.ExportedType); - } - } - - public Collection ExportedTypes - { - get - { - if (exported_types != null) - return exported_types; - - if (HasImage) - return Read(ref exported_types, this, (_, reader) => reader.ReadExportedTypes()); - - return exported_types = new Collection(); - } - } - - public MethodDefinition EntryPoint - { - get - { - if (entry_point != null) - return entry_point; - - if (HasImage) - return Read(ref entry_point, this, (_, reader) => reader.ReadEntryPoint()); - - return entry_point = null; - } - set { entry_point = value; } - } - - internal ModuleDefinition() - { - this.MetadataSystem = new MetadataSystem(); - this.token = new MetadataToken(TokenType.Module, 1); - } - - internal ModuleDefinition(Image image) - : this() - { - this.Image = image; - this.kind = image.Kind; - this.runtime = image.Runtime; - this.architecture = image.Architecture; - this.attributes = image.Attributes; - this.characteristics = image.Characteristics; - this.fq_name = image.FileName; - - this.reader = new MetadataReader(this); - } - - public bool HasTypeReference(string fullName) - { - return HasTypeReference(string.Empty, fullName); - } - - public bool HasTypeReference(string scope, string fullName) - { - CheckFullName(fullName); - - if (!HasImage) - return false; - - return GetTypeReference(scope, fullName) != null; - } - - public bool TryGetTypeReference(string fullName, out TypeReference type) - { - return TryGetTypeReference(string.Empty, fullName, out type); - } - - public bool TryGetTypeReference(string scope, string fullName, out TypeReference type) - { - CheckFullName(fullName); - - if (!HasImage) - { - type = null; - return false; - } - - return (type = GetTypeReference(scope, fullName)) != null; - } - - TypeReference GetTypeReference(string scope, string fullname) - { - return Read(new Row(scope, fullname), (row, reader) => reader.GetTypeReference(row.Col1, row.Col2)); - } - - public IEnumerable GetTypeReferences() - { - if (!HasImage) - return Empty.Array; - - return Read(this, (_, reader) => reader.GetTypeReferences()); - } - - public IEnumerable GetMemberReferences() - { - if (!HasImage) - return Empty.Array; - - return Read(this, (_, reader) => reader.GetMemberReferences()); - } - - public TypeReference GetType(string fullName, bool runtimeName) - { - return runtimeName - ? TypeParser.ParseType(this, fullName) - : GetType(fullName); - } - - public TypeDefinition GetType(string fullName) - { - CheckFullName(fullName); - - var position = fullName.IndexOf('/'); - if (position > 0) - return GetNestedType(fullName); - - return ((TypeDefinitionCollection)this.Types).GetType(fullName); - } - - public TypeDefinition GetType(string @namespace, string name) - { - Mixin.CheckName(name); - - return ((TypeDefinitionCollection)this.Types).GetType(@namespace ?? string.Empty, name); - } - - public IEnumerable GetTypes() - { - return GetTypes(Types); - } - - static IEnumerable GetTypes(Collection types) - { - for (int i = 0; i < types.Count; i++) - { - var type = types[i]; - - yield return type; - - if (!type.HasNestedTypes) - continue; - - foreach (var nested in GetTypes(type.NestedTypes)) - yield return nested; - } - } - - static void CheckFullName(string fullName) - { - if (fullName == null) - throw new ArgumentNullException("fullName"); - if (fullName.Length == 0) - throw new ArgumentException(); - } - - TypeDefinition GetNestedType(string fullname) - { - var names = fullname.Split('/'); - var type = GetType(names[0]); - - if (type == null) - return null; - - for (int i = 1; i < names.Length; i++) - { - var nested_type = Mixin.GetNestedType(type, names[i]); - if (nested_type == null) - return null; - - type = nested_type; - } - - return type; - } - - internal FieldDefinition Resolve(FieldReference field) - { - return MetadataResolver.Resolve(field); - } - - internal MethodDefinition Resolve(MethodReference method) - { - return MetadataResolver.Resolve(method); - } - - internal TypeDefinition Resolve(TypeReference type) - { - return MetadataResolver.Resolve(type); - } - - - public IMetadataTokenProvider LookupToken(int token) - { - return LookupToken(new MetadataToken((uint)token)); - } - - public IMetadataTokenProvider LookupToken(MetadataToken token) - { - return Read(token, (t, reader) => reader.LookupToken(t)); - } - - readonly object module_lock = new object(); - - internal object SyncRoot - { - get { return module_lock; } - } - - internal TRet Read(TItem item, Func read) - { - lock (module_lock) - { - var position = reader.position; - var context = reader.context; - - var ret = read(item, reader); - - reader.position = position; - reader.context = context; - - return ret; - } - } - - internal TRet Read(ref TRet variable, TItem item, Func read) where TRet : class - { - lock (module_lock) - { - if (variable != null) - return variable; - - var position = reader.position; - var context = reader.context; - - var ret = read(item, reader); - - reader.position = position; - reader.context = context; - - return variable = ret; - } - } - - public bool HasDebugHeader - { - get { return Image != null && !Image.Debug.IsZero; } - } - - public ImageDebugDirectory GetDebugHeader(out byte[] header) - { - if (!HasDebugHeader) - throw new InvalidOperationException(); - - return Image.GetDebugHeader(out header); - } - - void ProcessDebugHeader() - { - if (!HasDebugHeader) - return; - - byte[] header; - var directory = GetDebugHeader(out header); - - if (!symbol_reader.ProcessDebugHeader(directory, header)) - throw new InvalidOperationException(); - } - - - - public void ReadSymbols() - { - if (string.IsNullOrEmpty(fq_name)) - throw new InvalidOperationException(); - - var provider = SymbolProvider.GetPlatformReaderProvider(); - if (provider == null) - throw new InvalidOperationException(); - - ReadSymbols(provider.GetSymbolReader(this, fq_name)); - } - - public void ReadSymbols(ISymbolReader reader) - { - if (reader == null) - throw new ArgumentNullException("reader"); - - symbol_reader = reader; - - ProcessDebugHeader(); - } - - public static ModuleDefinition ReadModule(string fileName) - { - return ReadModule(fileName, new ReaderParameters(ReadingMode.Deferred)); - } - - public static ModuleDefinition ReadModule(Stream stream) - { - return ReadModule(stream, new ReaderParameters(ReadingMode.Deferred)); - } - - public static ModuleDefinition ReadModule(string fileName, ReaderParameters parameters) - { - using (var stream = GetFileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - return ReadModule(stream, parameters); - } - } - - static void CheckStream(object stream) - { - if (stream == null) - throw new ArgumentNullException("stream"); - } - - public static ModuleDefinition ReadModule(Stream stream, ReaderParameters parameters) - { - CheckStream(stream); - if (!stream.CanRead || !stream.CanSeek) - throw new ArgumentException(); - Mixin.CheckParameters(parameters); - - return ModuleReader.CreateModuleFrom( - ImageReader.ReadImageFrom(stream), - parameters); - } - - static Stream GetFileStream(string fileName, FileMode mode, FileAccess access, FileShare share) - { - if (fileName == null) - throw new ArgumentNullException("fileName"); - if (fileName.Length == 0) - throw new ArgumentException(); - - return new FileStream(fileName, mode, access, share); - } - - - - } - - static partial class Mixin - { - - public static void CheckParameters(object parameters) - { - if (parameters == null) - throw new ArgumentNullException("parameters"); - } - - public static bool HasImage(ModuleDefinition self) - { - return self != null && self.HasImage; - } - - public static bool IsCorlib(ModuleDefinition module) - { - if (module.Assembly == null) - return false; - - return module.Assembly.Name.Name == "mscorlib"; - } - - public static string GetFullyQualifiedName(Stream self) - { - - return string.Empty; - } - - public static TargetRuntime ParseRuntime(string self) - { - switch (self[1]) - { - case '1': - return self[3] == '0' - ? TargetRuntime.Net_1_0 - : TargetRuntime.Net_1_1; - case '2': - return TargetRuntime.Net_2_0; - case '4': - default: - return TargetRuntime.Net_4_0; - } - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleKind.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleKind.cs deleted file mode 100644 index c29da887..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleKind.cs +++ /dev/null @@ -1,64 +0,0 @@ -// -// ModuleKind.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - public enum ModuleKind { - Dll, - Console, - Windows, - NetModule, - } - - public enum TargetArchitecture { - I386, - AMD64, - IA64, - ARMv7, - } - - [Flags] - public enum ModuleAttributes { - ILOnly = 1, - Required32Bit = 2, - StrongNameSigned = 8, - Preferred32Bit = 0x00020000, - } - - [Flags] - public enum ModuleCharacteristics { - HighEntropyVA = 0x0020, - DynamicBase = 0x0040, - NoSEH = 0x0400, - NXCompat = 0x0100, - AppContainer = 0x1000, - TerminalServerAware = 0x8000, - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleReference.cs deleted file mode 100644 index 3934b3ce..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleReference.cs +++ /dev/null @@ -1,67 +0,0 @@ -// -// ModuleReference.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public class ModuleReference : IMetadataScope { - - string name; - - internal MetadataToken token; - - public string Name { - get { return name; } - set { name = value; } - } - - public virtual MetadataScopeType MetadataScopeType { - get { return MetadataScopeType.ModuleReference; } - } - - public MetadataToken MetadataToken { - get { return token; } - set { token = value; } - } - - internal ModuleReference () - { - this.token = new MetadataToken (TokenType.ModuleRef); - } - - public ModuleReference (string name) - : this () - { - this.name = name; - } - - public override string ToString () - { - return name; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/NativeType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/NativeType.cs deleted file mode 100644 index 88da9805..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/NativeType.cs +++ /dev/null @@ -1,73 +0,0 @@ -// -// NativeType.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public enum NativeType { - None = 0x66, - - Boolean = 0x02, - I1 = 0x03, - U1 = 0x04, - I2 = 0x05, - U2 = 0x06, - I4 = 0x07, - U4 = 0x08, - I8 = 0x09, - U8 = 0x0a, - R4 = 0x0b, - R8 = 0x0c, - LPStr = 0x14, - Int = 0x1f, - UInt = 0x20, - Func = 0x26, - Array = 0x2a, - - // Msft specific - Currency = 0x0f, - BStr = 0x13, - LPWStr = 0x15, - LPTStr = 0x16, - FixedSysString = 0x17, - IUnknown = 0x19, - IDispatch = 0x1a, - Struct = 0x1b, - IntF = 0x1c, - SafeArray = 0x1d, - FixedArray = 0x1e, - ByValStr = 0x22, - ANSIBStr = 0x23, - TBStr = 0x24, - VariantBool = 0x25, - ASAny = 0x28, - LPStruct = 0x2b, - CustomMarshaler = 0x2c, - Error = 0x2d, - Max = 0x50 - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeAttributes.cs deleted file mode 100644 index bb368382..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeAttributes.cs +++ /dev/null @@ -1,62 +0,0 @@ -// -// PInvokeAttributes.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - [Flags] - public enum PInvokeAttributes : ushort { - NoMangle = 0x0001, // PInvoke is to use the member name as specified - - // Character set - CharSetMask = 0x0006, - CharSetNotSpec = 0x0000, - CharSetAnsi = 0x0002, - CharSetUnicode = 0x0004, - CharSetAuto = 0x0006, - - SupportsLastError = 0x0040, // Information about target function. Not relevant for fields - - // Calling convetion - CallConvMask = 0x0700, - CallConvWinapi = 0x0100, - CallConvCdecl = 0x0200, - CallConvStdCall = 0x0300, - CallConvThiscall = 0x0400, - CallConvFastcall = 0x0500, - - BestFitMask = 0x0030, - BestFitEnabled = 0x0010, - BestFitDisabled = 0x0020, - - ThrowOnUnmappableCharMask = 0x3000, - ThrowOnUnmappableCharEnabled = 0x1000, - ThrowOnUnmappableCharDisabled = 0x2000, - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeInfo.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeInfo.cs deleted file mode 100644 index 9babf103..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeInfo.cs +++ /dev/null @@ -1,138 +0,0 @@ -// -// PInvokeInfo.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public sealed class PInvokeInfo { - - ushort attributes; - string entry_point; - ModuleReference module; - - public PInvokeAttributes Attributes { - get { return (PInvokeAttributes) attributes; } - set { attributes = (ushort) value; } - } - - public string EntryPoint { - get { return entry_point; } - set { entry_point = value; } - } - - public ModuleReference Module { - get { return module; } - set { module = value; } - } - - #region PInvokeAttributes - - public bool IsNoMangle { - get { return Mixin.GetAttributes(attributes,(ushort) PInvokeAttributes.NoMangle); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) PInvokeAttributes.NoMangle, value); } - } - - public bool IsCharSetNotSpec { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec, value); } - } - - public bool IsCharSetAnsi { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi, value); } - } - - public bool IsCharSetUnicode { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode, value); } - } - - public bool IsCharSetAuto { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto, value); } - } - - public bool SupportsLastError { - get { return Mixin.GetAttributes(attributes,(ushort) PInvokeAttributes.SupportsLastError); } - set { attributes =Mixin.SetAttributes(attributes,(ushort) PInvokeAttributes.SupportsLastError, value); } - } - - public bool IsCallConvWinapi { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi, value); } - } - - public bool IsCallConvCdecl { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl, value); } - } - - public bool IsCallConvStdCall { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall, value); } - } - - public bool IsCallConvThiscall { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall, value); } - } - - public bool IsCallConvFastcall { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall, value); } - } - - public bool IsBestFitEnabled { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled, value); } - } - - public bool IsBestFitDisabled { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled, value); } - } - - public bool IsThrowOnUnmappableCharEnabled { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled, value); } - } - - public bool IsThrowOnUnmappableCharDisabled { - get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharDisabled); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharDisabled, value); } - } - - #endregion - - public PInvokeInfo (PInvokeAttributes attributes, string entryPoint, ModuleReference module) - { - this.attributes = (ushort) attributes; - this.entry_point = entryPoint; - this.module = module; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterAttributes.cs deleted file mode 100644 index e0bc825d..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterAttributes.cs +++ /dev/null @@ -1,45 +0,0 @@ -// -// ParameterAttributes.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - [Flags] - public enum ParameterAttributes : ushort { - None = 0x0000, - In = 0x0001, // Param is [In] - Out = 0x0002, // Param is [Out] - Lcid = 0x0004, - Retval = 0x0008, - Optional = 0x0010, // Param is optional - HasDefault = 0x1000, // Param has default value - HasFieldMarshal = 0x2000, // Param has field marshal - Unused = 0xcfe0 // Reserved: shall be zero in a conforming implementation - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinition.cs deleted file mode 100644 index 3a6b3a8d..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinition.cs +++ /dev/null @@ -1,186 +0,0 @@ -// -// ParameterDefinition.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using Mono.Collections.Generic; - -namespace Mono.Cecil -{ - - public sealed class ParameterDefinition : ParameterReference, ICustomAttributeProvider, IConstantProvider, IMarshalInfoProvider - { - - ushort attributes; - - internal IMethodSignature method; - - object constant = Mixin.NotResolved; - Collection custom_attributes; - MarshalInfo marshal_info; - - public ParameterAttributes Attributes - { - get { return (ParameterAttributes)attributes; } - set { attributes = (ushort)value; } - } - - public IMethodSignature Method - { - get { return method; } - } - - public int Sequence - { - get - { - if (method == null) - return -1; - - return Mixin.HasImplicitThis(method) ? index + 1 : index; - } - } - - public bool HasConstant - { - get - { - Mixin.ResolveConstant(this, ref constant, parameter_type.Module); - - return constant != Mixin.NoValue; - } - set { if (!value) constant = Mixin.NoValue; } - } - - public object Constant - { - get { return HasConstant ? constant : null; } - set { constant = value; } - } - - public bool HasCustomAttributes - { - get - { - if (custom_attributes != null) - return custom_attributes.Count > 0; - - return Mixin.GetHasCustomAttributes(this, parameter_type.Module); - } - } - - public Collection CustomAttributes - { - get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, parameter_type.Module)); } - } - - public bool HasMarshalInfo - { - get - { - if (marshal_info != null) - return true; - - return Mixin.GetHasMarshalInfo(this, parameter_type.Module); - } - } - - public MarshalInfo MarshalInfo - { - get { return marshal_info ?? (Mixin.GetMarshalInfo(this, ref marshal_info, parameter_type.Module)); } - set { marshal_info = value; } - } - - #region ParameterAttributes - - public bool IsIn - { - get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.In); } - set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.In, value); } - } - - public bool IsOut - { - get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.Out); } - set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.Out, value); } - } - - public bool IsLcid - { - get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.Lcid); } - set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.Lcid, value); } - } - - public bool IsReturnValue - { - get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.Retval); } - set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.Retval, value); } - } - - public bool IsOptional - { - get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.Optional); } - set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.Optional, value); } - } - - public bool HasDefault - { - get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.HasDefault); } - set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.HasDefault, value); } - } - - public bool HasFieldMarshal - { - get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.HasFieldMarshal); } - set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.HasFieldMarshal, value); } - } - - #endregion - - internal ParameterDefinition(TypeReference parameterType, IMethodSignature method) - : this(string.Empty, ParameterAttributes.None, parameterType) - { - this.method = method; - } - - public ParameterDefinition(TypeReference parameterType) - : this(string.Empty, ParameterAttributes.None, parameterType) - { - } - - public ParameterDefinition(string name, ParameterAttributes attributes, TypeReference parameterType) - : base(name, parameterType) - { - this.attributes = (ushort)attributes; - this.token = new MetadataToken(TokenType.Param); - } - - public override ParameterDefinition Resolve() - { - return this; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinitionCollection.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinitionCollection.cs deleted file mode 100644 index bd8b1c13..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinitionCollection.cs +++ /dev/null @@ -1,80 +0,0 @@ -// -// ParameterDefinitionCollection.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using Mono.Collections.Generic; - -namespace Mono.Cecil { - - sealed class ParameterDefinitionCollection : Collection { - - readonly IMethodSignature method; - - internal ParameterDefinitionCollection (IMethodSignature method) - { - this.method = method; - } - - internal ParameterDefinitionCollection (IMethodSignature method, int capacity) - : base (capacity) - { - this.method = method; - } - - protected override void OnAdd (ParameterDefinition item, int index) - { - item.method = method; - item.index = index; - } - - protected override void OnInsert (ParameterDefinition item, int index) - { - item.method = method; - item.index = index; - - for (int i = index; i < size; i++) - items [i].index = i + 1; - } - - protected override void OnSet (ParameterDefinition item, int index) - { - item.method = method; - item.index = index; - } - - protected override void OnRemove (ParameterDefinition item, int index) - { - item.method = null; - item.index = -1; - - for (int i = index + 1; i < size; i++) - items [i].index = i - 1; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterReference.cs deleted file mode 100644 index 46b057cd..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterReference.cs +++ /dev/null @@ -1,75 +0,0 @@ -// -// ParameterReference.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - public abstract class ParameterReference : IMetadataTokenProvider { - - string name; - internal int index = -1; - protected TypeReference parameter_type; - internal MetadataToken token; - - public string Name { - get { return name; } - set { name = value; } - } - - public int Index { - get { return index; } - } - - public TypeReference ParameterType { - get { return parameter_type; } - set { parameter_type = value; } - } - - public MetadataToken MetadataToken { - get { return token; } - set { token = value; } - } - - internal ParameterReference (string name, TypeReference parameterType) - { - if (parameterType == null) - throw new ArgumentNullException ("parameterType"); - - this.name = name ?? string.Empty; - this.parameter_type = parameterType; - } - - public override string ToString () - { - return name; - } - - public abstract ParameterDefinition Resolve (); - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PinnedType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PinnedType.cs deleted file mode 100644 index ff59cfb7..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PinnedType.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -// PinnedType.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using MD = Mono.Cecil.Metadata; - -namespace Mono.Cecil { - - public sealed class PinnedType : TypeSpecification { - - public override bool IsValueType { - get { return false; } - set { throw new InvalidOperationException (); } - } - - public override bool IsPinned { - get { return true; } - } - - public PinnedType (TypeReference type) - : base (type) - { - Mixin.CheckType (type); - this.etype = MD.ElementType.Pinned; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PointerType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PointerType.cs deleted file mode 100644 index a142e144..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PointerType.cs +++ /dev/null @@ -1,61 +0,0 @@ -// -// PointerType.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using MD = Mono.Cecil.Metadata; - -namespace Mono.Cecil { - - public sealed class PointerType : TypeSpecification { - - public override string Name { - get { return base.Name + "*"; } - } - - public override string FullName { - get { return base.FullName + "*"; } - } - - public override bool IsValueType { - get { return false; } - set { throw new InvalidOperationException (); } - } - - public override bool IsPointer { - get { return true; } - } - - public PointerType (TypeReference type) - : base (type) - { - Mixin.CheckType (type); - this.etype = MD.ElementType.Ptr; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyAttributes.cs deleted file mode 100644 index 1be0413f..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyAttributes.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -// PropertyAttributes.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -namespace Mono.Cecil { - - [Flags] - public enum PropertyAttributes : ushort { - None = 0x0000, - SpecialName = 0x0200, // Property is special - RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding - HasDefault = 0x1000, // Property has default - Unused = 0xe9ff // Reserved: shall be zero in a conforming implementation - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyReference.cs deleted file mode 100644 index 0dcfc952..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyReference.cs +++ /dev/null @@ -1,59 +0,0 @@ -// -// PropertyReference.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using Mono.Collections.Generic; - -namespace Mono.Cecil { - - public abstract class PropertyReference : MemberReference { - - TypeReference property_type; - - public TypeReference PropertyType { - get { return property_type; } - set { property_type = value; } - } - - public abstract Collection Parameters { - get; - } - - internal PropertyReference (string name, TypeReference propertyType) - : base (name) - { - if (propertyType == null) - throw new ArgumentNullException ("propertyType"); - - property_type = propertyType; - } - - public abstract PropertyDefinition Resolve (); - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ReferenceType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ReferenceType.cs deleted file mode 100644 index 7940c617..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ReferenceType.cs +++ /dev/null @@ -1,61 +0,0 @@ -// -// ByReferenceType.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using MD = Mono.Cecil.Metadata; - -namespace Mono.Cecil { - - public sealed class ByReferenceType : TypeSpecification { - - public override string Name { - get { return base.Name + "&"; } - } - - public override string FullName { - get { return base.FullName + "&"; } - } - - public override bool IsValueType { - get { return false; } - set { throw new InvalidOperationException (); } - } - - public override bool IsByReference { - get { return true; } - } - - public ByReferenceType (TypeReference type) - : base (type) - { - Mixin.CheckType (type); - this.etype = MD.ElementType.ByRef; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/Resource.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/Resource.cs deleted file mode 100644 index 94b3e156..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/Resource.cs +++ /dev/null @@ -1,76 +0,0 @@ -// -// ResourceType.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public enum ResourceType { - Linked, - Embedded, - AssemblyLinked, - } - - public abstract class Resource { - - string name; - uint attributes; - - public string Name { - get { return name; } - set { name = value; } - } - - public ManifestResourceAttributes Attributes { - get { return (ManifestResourceAttributes) attributes; } - set { attributes = (uint) value; } - } - - public abstract ResourceType ResourceType { - get; - } - - #region ManifestResourceAttributes - - public bool IsPublic { - get { return Mixin.GetMaskedAttributes(attributes,(uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public, value); } - } - - public bool IsPrivate { - get { return Mixin.GetMaskedAttributes(attributes,(uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private); } - set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private, value); } - } - - #endregion - - internal Resource (string name, ManifestResourceAttributes attributes) - { - this.name = name; - this.attributes = (uint) attributes; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/SecurityDeclaration.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/SecurityDeclaration.cs deleted file mode 100644 index 1a23403e..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/SecurityDeclaration.cs +++ /dev/null @@ -1,210 +0,0 @@ -// -// SecurityDeclaration.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Threading; -using Mono.Collections.Generic; - -namespace Mono.Cecil -{ - - public enum SecurityAction : ushort - { - Request = 1, - Demand = 2, - Assert = 3, - Deny = 4, - PermitOnly = 5, - LinkDemand = 6, - InheritDemand = 7, - RequestMinimum = 8, - RequestOptional = 9, - RequestRefuse = 10, - PreJitGrant = 11, - PreJitDeny = 12, - NonCasDemand = 13, - NonCasLinkDemand = 14, - NonCasInheritance = 15 - } - - public interface ISecurityDeclarationProvider : IMetadataTokenProvider - { - - bool HasSecurityDeclarations { get; } - Collection SecurityDeclarations { get; } - } - - public sealed class SecurityAttribute : ICustomAttribute - { - - TypeReference attribute_type; - - internal Collection fields; - internal Collection properties; - - public TypeReference AttributeType - { - get { return attribute_type; } - set { attribute_type = value; } - } - - public bool HasFields - { - get { return !Mixin.IsNullOrEmpty(fields); } - } - - public Collection Fields - { - get { return fields ?? (fields = new Collection()); } - } - - public bool HasProperties - { - get { return !Mixin.IsNullOrEmpty(properties); } - } - - public Collection Properties - { - get { return properties ?? (properties = new Collection()); } - } - - public SecurityAttribute(TypeReference attributeType) - { - this.attribute_type = attributeType; - } - } - - public sealed class SecurityDeclaration - { - - readonly internal uint signature; - byte[] blob; - readonly ModuleDefinition module; - - internal bool resolved; - SecurityAction action; - internal Collection security_attributes; - - public SecurityAction Action - { - get { return action; } - set { action = value; } - } - - public bool HasSecurityAttributes - { - get - { - Resolve(); - - return !Mixin.IsNullOrEmpty(security_attributes); - } - } - - public Collection SecurityAttributes - { - get - { - Resolve(); - - return security_attributes ?? (security_attributes = new Collection()); - } - } - - internal bool HasImage - { - get { return module != null && module.HasImage; } - } - - internal SecurityDeclaration(SecurityAction action, uint signature, ModuleDefinition module) - { - this.action = action; - this.signature = signature; - this.module = module; - } - - public SecurityDeclaration(SecurityAction action) - { - this.action = action; - this.resolved = true; - } - - public SecurityDeclaration(SecurityAction action, byte[] blob) - { - this.action = action; - this.resolved = false; - this.blob = blob; - } - - public byte[] GetBlob() - { - if (blob != null) - return blob; - - if (!HasImage || signature == 0) - throw new NotSupportedException(); - - return blob = module.Read(this, (declaration, reader) => reader.ReadSecurityDeclarationBlob(declaration.signature)); - } - - void Resolve() - { - if (resolved || !HasImage) - return; - - module.Read(this, (declaration, reader) => - { - reader.ReadSecurityDeclarationSignature(declaration); - return this; - }); - - resolved = true; - } - } - - static partial class Mixin - { - - public static bool GetHasSecurityDeclarations( - ISecurityDeclarationProvider self, - ModuleDefinition module) - { - return Mixin.HasImage(module) && module.Read(self, (provider, reader) => reader.HasSecurityDeclarations(provider)); - } - - public static Collection GetSecurityDeclarations( - ISecurityDeclarationProvider self, - ref Collection variable, - ModuleDefinition module) - { - return Mixin.HasImage(module) - ? module.Read(ref variable, self, (provider, reader) => reader.ReadSecurityDeclarations(provider)) - : variable = new Collection(); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/SentinelType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/SentinelType.cs deleted file mode 100644 index 664d75bf..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/SentinelType.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -// SentinelType.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using MD = Mono.Cecil.Metadata; - -namespace Mono.Cecil { - - public sealed class SentinelType : TypeSpecification { - - public override bool IsValueType { - get { return false; } - set { throw new InvalidOperationException (); } - } - - public override bool IsSentinel { - get { return true; } - } - - public SentinelType (TypeReference type) - : base (type) - { - Mixin.CheckType (type); - this.etype = MD.ElementType.Sentinel; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TargetRuntime.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TargetRuntime.cs deleted file mode 100644 index 9b49a5f7..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TargetRuntime.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// TargetRuntime.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public enum TargetRuntime { - Net_1_0, - Net_1_1, - Net_2_0, - Net_4_0, - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinition.cs deleted file mode 100644 index a71b3571..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinition.cs +++ /dev/null @@ -1,599 +0,0 @@ -// -// TypeDefinition.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using Mono.Cecil.Metadata; -using Mono.Collections.Generic; - -namespace Mono.Cecil -{ - - public sealed class TypeDefinition : TypeReference, IMemberDefinition, ISecurityDeclarationProvider - { - - uint attributes; - TypeReference base_type; - internal Range fields_range; - internal Range methods_range; - - short packing_size = Mixin.NotResolvedMarker; - int class_size = Mixin.NotResolvedMarker; - - Collection interfaces; - Collection nested_types; - Collection methods; - Collection fields; - Collection events; - Collection properties; - Collection custom_attributes; - Collection security_declarations; - - public TypeAttributes Attributes - { - get { return (TypeAttributes)attributes; } - set { attributes = (uint)value; } - } - - public TypeReference BaseType - { - get { return base_type; } - set { base_type = value; } - } - - void ResolveLayout() - { - if (packing_size != Mixin.NotResolvedMarker || class_size != Mixin.NotResolvedMarker) - return; - - if (!HasImage) - { - packing_size = Mixin.NoDataMarker; - class_size = Mixin.NoDataMarker; - return; - } - - var row = Module.Read(this, (type, reader) => reader.ReadTypeLayout(type)); - - packing_size = row.Col1; - class_size = row.Col2; - } - - public bool HasLayoutInfo - { - get - { - if (packing_size >= 0 || class_size >= 0) - return true; - - ResolveLayout(); - - return packing_size >= 0 || class_size >= 0; - } - } - - public short PackingSize - { - get - { - if (packing_size >= 0) - return packing_size; - - ResolveLayout(); - - return packing_size >= 0 ? packing_size : (short)-1; - } - set { packing_size = value; } - } - - public int ClassSize - { - get - { - if (class_size >= 0) - return class_size; - - ResolveLayout(); - - return class_size >= 0 ? class_size : -1; - } - set { class_size = value; } - } - - public bool HasInterfaces - { - get - { - if (interfaces != null) - return interfaces.Count > 0; - - if (HasImage) - return Module.Read(this, (type, reader) => reader.HasInterfaces(type)); - - return false; - } - } - - public Collection Interfaces - { - get - { - if (interfaces != null) - return interfaces; - - if (HasImage) - return Module.Read(ref interfaces, this, (type, reader) => reader.ReadInterfaces(type)); - - return interfaces = new Collection(); - } - } - - public bool HasNestedTypes - { - get - { - if (nested_types != null) - return nested_types.Count > 0; - - if (HasImage) - return Module.Read(this, (type, reader) => reader.HasNestedTypes(type)); - - return false; - } - } - - public Collection NestedTypes - { - get - { - if (nested_types != null) - return nested_types; - - if (HasImage) - return Module.Read(ref nested_types, this, (type, reader) => reader.ReadNestedTypes(type)); - - return nested_types = new MemberDefinitionCollection(this); - } - } - - public bool HasMethods - { - get - { - if (methods != null) - return methods.Count > 0; - - if (HasImage) - return methods_range.Length > 0; - - return false; - } - } - - public Collection Methods - { - get - { - if (methods != null) - return methods; - - if (HasImage) - return Module.Read(ref methods, this, (type, reader) => reader.ReadMethods(type)); - - return methods = new MemberDefinitionCollection(this); - } - } - - public bool HasFields - { - get - { - if (fields != null) - return fields.Count > 0; - - if (HasImage) - return fields_range.Length > 0; - - return false; - } - } - - public Collection Fields - { - get - { - if (fields != null) - return fields; - - if (HasImage) - return Module.Read(ref fields, this, (type, reader) => reader.ReadFields(type)); - - return fields = new MemberDefinitionCollection(this); - } - } - - public bool HasEvents - { - get - { - if (events != null) - return events.Count > 0; - - if (HasImage) - return Module.Read(this, (type, reader) => reader.HasEvents(type)); - - return false; - } - } - - public Collection Events - { - get - { - if (events != null) - return events; - - if (HasImage) - return Module.Read(ref events, this, (type, reader) => reader.ReadEvents(type)); - - return events = new MemberDefinitionCollection(this); - } - } - - public bool HasProperties - { - get - { - if (properties != null) - return properties.Count > 0; - - if (HasImage) - return Module.Read(this, (type, reader) => reader.HasProperties(type)); - - return false; - } - } - - public Collection Properties - { - get - { - if (properties != null) - return properties; - - if (HasImage) - return Module.Read(ref properties, this, (type, reader) => reader.ReadProperties(type)); - - return properties = new MemberDefinitionCollection(this); - } - } - - public bool HasSecurityDeclarations - { - get - { - if (security_declarations != null) - return security_declarations.Count > 0; - - return Mixin.GetHasSecurityDeclarations(this, Module); - } - } - - public Collection SecurityDeclarations - { - get { return security_declarations ?? (Mixin.GetSecurityDeclarations(this, ref security_declarations, Module)); } - } - - public bool HasCustomAttributes - { - get - { - if (custom_attributes != null) - return custom_attributes.Count > 0; - - return Mixin.GetHasCustomAttributes(this, Module); - } - } - - public Collection CustomAttributes - { - get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } - } - - public override bool HasGenericParameters - { - get - { - if (generic_parameters != null) - return generic_parameters.Count > 0; - - return Mixin.GetHasGenericParameters(this, Module); - } - } - - public override Collection GenericParameters - { - get { return generic_parameters ?? (Mixin.GetGenericParameters(this,ref generic_parameters, Module)); } - } - - #region TypeAttributes - - public bool IsNotPublic - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NotPublic); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NotPublic, value); } - } - - public bool IsPublic - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.Public); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.Public, value); } - } - - public bool IsNestedPublic - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedPublic); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedPublic, value); } - } - - public bool IsNestedPrivate - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedPrivate); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedPrivate, value); } - } - - public bool IsNestedFamily - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamily); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamily, value); } - } - - public bool IsNestedAssembly - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedAssembly); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedAssembly, value); } - } - - public bool IsNestedFamilyAndAssembly - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamANDAssem); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamANDAssem, value); } - } - - public bool IsNestedFamilyOrAssembly - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamORAssem); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamORAssem, value); } - } - - public bool IsAutoLayout - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.AutoLayout); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.AutoLayout, value); } - } - - public bool IsSequentialLayout - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.SequentialLayout); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.SequentialLayout, value); } - } - - public bool IsExplicitLayout - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.ExplicitLayout); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.ExplicitLayout, value); } - } - - public bool IsClass - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.ClassSemanticMask, (uint)TypeAttributes.Class); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.ClassSemanticMask, (uint)TypeAttributes.Class, value); } - } - - public bool IsInterface - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.ClassSemanticMask, (uint)TypeAttributes.Interface); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.ClassSemanticMask, (uint)TypeAttributes.Interface, value); } - } - - public bool IsAbstract - { - get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.Abstract); } - set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.Abstract, value); } - } - - public bool IsSealed - { - get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.Sealed); } - set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.Sealed, value); } - } - - public bool IsSpecialName - { - get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.SpecialName); } - set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.SpecialName, value); } - } - - public bool IsImport - { - get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.Import); } - set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.Import, value); } - } - - public bool IsSerializable - { - get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.Serializable); } - set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.Serializable, value); } - } - - public bool IsWindowsRuntime - { - get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.WindowsRuntime); } - set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.WindowsRuntime, value); } - } - - public bool IsAnsiClass - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.AnsiClass); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.AnsiClass, value); } - } - - public bool IsUnicodeClass - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.UnicodeClass); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.UnicodeClass, value); } - } - - public bool IsAutoClass - { - get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.AutoClass); } - set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.AutoClass, value); } - } - - public bool IsBeforeFieldInit - { - get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.BeforeFieldInit); } - set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.BeforeFieldInit, value); } - } - - public bool IsRuntimeSpecialName - { - get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.RTSpecialName); } - set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.RTSpecialName, value); } - } - - public bool HasSecurity - { - get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.HasSecurity); } - set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.HasSecurity, value); } - } - - #endregion - - public bool IsEnum - { - get { return base_type != null && Mixin.IsTypeOf(base_type, "System", "Enum"); } - } - - public override bool IsValueType - { - get - { - if (base_type == null) - return false; - - return Mixin.IsTypeOf(base_type, "System", "Enum") || (Mixin.IsTypeOf(base_type, "System", "ValueType") && !Mixin.IsTypeOf(this, "System", "Enum")); - } - } - - public override bool IsPrimitive - { - get - { - ElementType primitive_etype; - return MetadataSystem.TryGetPrimitiveElementType(this, out primitive_etype); - } - } - - public override MetadataType MetadataType - { - get - { - ElementType primitive_etype; - if (MetadataSystem.TryGetPrimitiveElementType(this, out primitive_etype)) - return (MetadataType)primitive_etype; - - return base.MetadataType; - } - } - - public override bool IsDefinition - { - get { return true; } - } - - public new TypeDefinition DeclaringType - { - get { return (TypeDefinition)base.DeclaringType; } - set { base.DeclaringType = value; } - } - - public TypeDefinition(string @namespace, string name, TypeAttributes attributes) - : base(@namespace, name) - { - this.attributes = (uint)attributes; - this.token = new MetadataToken(TokenType.TypeDef); - } - - public TypeDefinition(string @namespace, string name, TypeAttributes attributes, TypeReference baseType) : - this(@namespace, name, attributes) - { - this.BaseType = baseType; - } - - public override TypeDefinition Resolve() - { - return this; - } - } - - static partial class Mixin - { - - public static TypeReference GetEnumUnderlyingType(TypeDefinition self) - { - var fields = self.Fields; - - for (int i = 0; i < fields.Count; i++) - { - var field = fields[i]; - if (!field.IsStatic) - return field.FieldType; - } - - throw new ArgumentException(); - } - - public static TypeDefinition GetNestedType(TypeDefinition self, string name) - { - if (!self.HasNestedTypes) - return null; - - var nested_types = self.NestedTypes; - - for (int i = 0; i < nested_types.Count; i++) - { - var nested_type = nested_types[i]; - if (nested_type.Name == name) - return nested_type; - } - - return null; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeParser.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeParser.cs deleted file mode 100644 index 38d1a49e..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeParser.cs +++ /dev/null @@ -1,584 +0,0 @@ -// -// TypeParser.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Text; - -using Mono.Cecil.Metadata; - -namespace Mono.Cecil -{ - - class TypeParser - { - - class Type - { - public const int Ptr = -1; - public const int ByRef = -2; - public const int SzArray = -3; - - public string type_fullname; - public string[] nested_names; - public int arity; - public int[] specs; - public Type[] generic_arguments; - public string assembly; - } - - readonly string fullname; - readonly int length; - - int position; - - TypeParser(string fullname) - { - this.fullname = fullname; - this.length = fullname.Length; - } - - Type ParseType(bool fq_name) - { - var type = new Type(); - type.type_fullname = ParsePart(); - - type.nested_names = ParseNestedNames(); - - if (TryGetArity(type)) - type.generic_arguments = ParseGenericArguments(type.arity); - - type.specs = ParseSpecs(); - - if (fq_name) - type.assembly = ParseAssemblyName(); - - return type; - } - - static bool TryGetArity(Type type) - { - int arity = 0; - - TryAddArity(type.type_fullname, ref arity); - - var nested_names = type.nested_names; - if (!Mixin.IsNullOrEmpty(nested_names)) - { - for (int i = 0; i < nested_names.Length; i++) - TryAddArity(nested_names[i], ref arity); - } - - type.arity = arity; - return arity > 0; - } - - static bool TryGetArity(string name, out int arity) - { - arity = 0; - var index = name.LastIndexOf('`'); - if (index == -1) - return false; - - return ParseInt32(name.Substring(index + 1), out arity); - } - - static bool ParseInt32(string value, out int result) - { -#if CF - try { - result = int.Parse (value); - return true; - } catch { - result = 0; - return false; - } -#else - return int.TryParse(value, out result); -#endif - } - - static void TryAddArity(string name, ref int arity) - { - int type_arity; - if (!TryGetArity(name, out type_arity)) - return; - - arity += type_arity; - } - - string ParsePart() - { - int start = position; - while (position < length && !IsDelimiter(fullname[position])) - position++; - - return fullname.Substring(start, position - start); - } - - static bool IsDelimiter(char chr) - { - return "+,[]*&".IndexOf(chr) != -1; - } - - void TryParseWhiteSpace() - { - while (position < length && Char.IsWhiteSpace(fullname[position])) - position++; - } - - string[] ParseNestedNames() - { - string[] nested_names = null; - while (TryParse('+')) - Add(ref nested_names, ParsePart()); - - return nested_names; - } - - bool TryParse(char chr) - { - if (position < length && fullname[position] == chr) - { - position++; - return true; - } - - return false; - } - - static void Add(ref T[] array, T item) - { - if (array == null) - { - array = new[] { item }; - return; - } - -#if !CF - Array.Resize(ref array, array.Length + 1); -#else - var copy = new T [array.Length + 1]; - Array.Copy (array, copy, array.Length); - array = copy; -#endif - array[array.Length - 1] = item; - } - - int[] ParseSpecs() - { - int[] specs = null; - - while (position < length) - { - switch (fullname[position]) - { - case '*': - position++; - Add(ref specs, Type.Ptr); - break; - case '&': - position++; - Add(ref specs, Type.ByRef); - break; - case '[': - position++; - switch (fullname[position]) - { - case ']': - position++; - Add(ref specs, Type.SzArray); - break; - case '*': - position++; - Add(ref specs, 1); - break; - default: - var rank = 1; - while (TryParse(',')) - rank++; - - Add(ref specs, rank); - - TryParse(']'); - break; - } - break; - default: - return specs; - } - } - - return specs; - } - - Type[] ParseGenericArguments(int arity) - { - Type[] generic_arguments = null; - - if (position == length || fullname[position] != '[') - return generic_arguments; - - TryParse('['); - - for (int i = 0; i < arity; i++) - { - var fq_argument = TryParse('['); - Add(ref generic_arguments, ParseType(fq_argument)); - if (fq_argument) - TryParse(']'); - - TryParse(','); - TryParseWhiteSpace(); - } - - TryParse(']'); - - return generic_arguments; - } - - string ParseAssemblyName() - { - if (!TryParse(',')) - return string.Empty; - - TryParseWhiteSpace(); - - var start = position; - while (position < length) - { - var chr = fullname[position]; - if (chr == '[' || chr == ']') - break; - - position++; - } - - return fullname.Substring(start, position - start); - } - - public static TypeReference ParseType(ModuleDefinition module, string fullname) - { - if (string.IsNullOrEmpty(fullname)) - return null; - - var parser = new TypeParser(fullname); - return GetTypeReference(module, parser.ParseType(true)); - } - - static TypeReference GetTypeReference(ModuleDefinition module, Type type_info) - { - TypeReference type; - if (!TryGetDefinition(module, type_info, out type)) - type = CreateReference(type_info, module, GetMetadataScope(module, type_info)); - - return CreateSpecs(type, type_info); - } - - static TypeReference CreateSpecs(TypeReference type, Type type_info) - { - type = TryCreateGenericInstanceType(type, type_info); - - var specs = type_info.specs; - if (Mixin.IsNullOrEmpty(specs)) - return type; - - for (int i = 0; i < specs.Length; i++) - { - switch (specs[i]) - { - case Type.Ptr: - type = new PointerType(type); - break; - case Type.ByRef: - type = new ByReferenceType(type); - break; - case Type.SzArray: - type = new ArrayType(type); - break; - default: - var array = new ArrayType(type); - array.Dimensions.Clear(); - - for (int j = 0; j < specs[i]; j++) - array.Dimensions.Add(new ArrayDimension()); - - type = array; - break; - } - } - - return type; - } - - static TypeReference TryCreateGenericInstanceType(TypeReference type, Type type_info) - { - var generic_arguments = type_info.generic_arguments; - if (Mixin.IsNullOrEmpty(generic_arguments)) - return type; - - var instance = new GenericInstanceType(type); - var instance_arguments = instance.GenericArguments; - - for (int i = 0; i < generic_arguments.Length; i++) - instance_arguments.Add(GetTypeReference(type.Module, generic_arguments[i])); - - return instance; - } - - public static void SplitFullName(string fullname, out string @namespace, out string name) - { - var last_dot = fullname.LastIndexOf('.'); - - if (last_dot == -1) - { - @namespace = string.Empty; - name = fullname; - } - else - { - @namespace = fullname.Substring(0, last_dot); - name = fullname.Substring(last_dot + 1); - } - } - - static TypeReference CreateReference(Type type_info, ModuleDefinition module, IMetadataScope scope) - { - string @namespace, name; - SplitFullName(type_info.type_fullname, out @namespace, out name); - - var type = new TypeReference(@namespace, name, module, scope); - MetadataSystem.TryProcessPrimitiveTypeReference(type); - - AdjustGenericParameters(type); - - var nested_names = type_info.nested_names; - if (Mixin.IsNullOrEmpty(nested_names)) - return type; - - for (int i = 0; i < nested_names.Length; i++) - { - type = new TypeReference(string.Empty, nested_names[i], module, null) - { - DeclaringType = type, - }; - - AdjustGenericParameters(type); - } - - return type; - } - - static void AdjustGenericParameters(TypeReference type) - { - int arity; - if (!TryGetArity(type.Name, out arity)) - return; - - for (int i = 0; i < arity; i++) - type.GenericParameters.Add(new GenericParameter(type)); - } - - static IMetadataScope GetMetadataScope(ModuleDefinition module, Type type_info) - { - if (string.IsNullOrEmpty(type_info.assembly)) - return module.TypeSystem.Corlib; - - return MatchReference(module, AssemblyNameReference.Parse(type_info.assembly)); - } - - static AssemblyNameReference MatchReference(ModuleDefinition module, AssemblyNameReference pattern) - { - var references = module.AssemblyReferences; - - for (int i = 0; i < references.Count; i++) - { - var reference = references[i]; - if (reference.FullName == pattern.FullName) - return reference; - } - - return pattern; - } - - static bool TryGetDefinition(ModuleDefinition module, Type type_info, out TypeReference type) - { - type = null; - if (!TryCurrentModule(module, type_info)) - return false; - - var typedef = module.GetType(type_info.type_fullname); - if (typedef == null) - return false; - - var nested_names = type_info.nested_names; - if (!Mixin.IsNullOrEmpty(nested_names)) - { - for (int i = 0; i < nested_names.Length; i++) - typedef = Mixin.GetNestedType(typedef, nested_names[i]); - } - - type = typedef; - return true; - } - - static bool TryCurrentModule(ModuleDefinition module, Type type_info) - { - if (string.IsNullOrEmpty(type_info.assembly)) - return true; - - if (module.assembly != null && module.assembly.Name.FullName == type_info.assembly) - return true; - - return false; - } - - public static string ToParseable(TypeReference type) - { - if (type == null) - return null; - - var name = new StringBuilder(); - AppendType(type, name, true, true); - return name.ToString(); - } - - static void AppendType(TypeReference type, StringBuilder name, bool fq_name, bool top_level) - { - var declaring_type = type.DeclaringType; - if (declaring_type != null) - { - AppendType(declaring_type, name, false, top_level); - name.Append('+'); - } - - var @namespace = type.Namespace; - if (!string.IsNullOrEmpty(@namespace)) - { - name.Append(@namespace); - name.Append('.'); - } - - name.Append(type.GetElementType().Name); - - if (!fq_name) - return; - - if (Mixin.IsTypeSpecification(type)) - AppendTypeSpecification((TypeSpecification)type, name); - - if (RequiresFullyQualifiedName(type, top_level)) - { - name.Append(", "); - name.Append(GetScopeFullName(type)); - } - } - - static string GetScopeFullName(TypeReference type) - { - var scope = type.Scope; - switch (scope.MetadataScopeType) - { - case MetadataScopeType.AssemblyNameReference: - return ((AssemblyNameReference)scope).FullName; - case MetadataScopeType.ModuleDefinition: - return ((ModuleDefinition)scope).Assembly.Name.FullName; - } - - throw new ArgumentException(); - } - - static void AppendTypeSpecification(TypeSpecification type, StringBuilder name) - { - if (Mixin.IsTypeSpecification(type.ElementType)) - AppendTypeSpecification((TypeSpecification)type.ElementType, name); - - switch (type.etype) - { - case ElementType.Ptr: - name.Append('*'); - break; - case ElementType.ByRef: - name.Append('&'); - break; - case ElementType.SzArray: - case ElementType.Array: - var array = (ArrayType)type; - if (array.IsVector) - { - name.Append("[]"); - } - else - { - name.Append('['); - for (int i = 1; i < array.Rank; i++) - name.Append(','); - name.Append(']'); - } - break; - case ElementType.GenericInst: - var instance = (GenericInstanceType)type; - var arguments = instance.GenericArguments; - - name.Append('['); - - for (int i = 0; i < arguments.Count; i++) - { - if (i > 0) - name.Append(','); - - var argument = arguments[i]; - var requires_fqname = argument.Scope != argument.Module; - - if (requires_fqname) - name.Append('['); - - AppendType(argument, name, true, false); - - if (requires_fqname) - name.Append(']'); - } - - name.Append(']'); - break; - default: - return; - } - } - - static bool RequiresFullyQualifiedName(TypeReference type, bool top_level) - { - if (type.Scope == type.Module) - return false; - - if (type.Scope.Name == "mscorlib" && top_level) - return false; - - return true; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeReference.cs deleted file mode 100644 index 1d61be24..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeReference.cs +++ /dev/null @@ -1,378 +0,0 @@ -// -// TypeReference.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using Mono.Cecil.Metadata; -using Mono.Collections.Generic; - -namespace Mono.Cecil -{ - - public enum MetadataType : byte - { - Void = ElementType.Void, - Boolean = ElementType.Boolean, - Char = ElementType.Char, - SByte = ElementType.I1, - Byte = ElementType.U1, - Int16 = ElementType.I2, - UInt16 = ElementType.U2, - Int32 = ElementType.I4, - UInt32 = ElementType.U4, - Int64 = ElementType.I8, - UInt64 = ElementType.U8, - Single = ElementType.R4, - Double = ElementType.R8, - String = ElementType.String, - Pointer = ElementType.Ptr, - ByReference = ElementType.ByRef, - ValueType = ElementType.ValueType, - Class = ElementType.Class, - Var = ElementType.Var, - Array = ElementType.Array, - GenericInstance = ElementType.GenericInst, - TypedByReference = ElementType.TypedByRef, - IntPtr = ElementType.I, - UIntPtr = ElementType.U, - FunctionPointer = ElementType.FnPtr, - Object = ElementType.Object, - MVar = ElementType.MVar, - RequiredModifier = ElementType.CModReqD, - OptionalModifier = ElementType.CModOpt, - Sentinel = ElementType.Sentinel, - Pinned = ElementType.Pinned, - } - - public class TypeReference : MemberReference, IGenericParameterProvider, IGenericContext - { - - string @namespace; - bool value_type; - int hashCode = -1; - static int instance_id; - internal IMetadataScope scope; - internal ModuleDefinition module; - - internal ElementType etype = ElementType.None; - - string fullname; - - protected Collection generic_parameters; - - public override string Name - { - get { return base.Name; } - set - { - base.Name = value; - fullname = null; - } - } - - public virtual string Namespace - { - get { return @namespace; } - set - { - @namespace = value; - fullname = null; - } - } - - public virtual bool IsValueType - { - get { return value_type; } - set { value_type = value; } - } - - public override ModuleDefinition Module - { - get - { - if (module != null) - return module; - - var declaring_type = this.DeclaringType; - if (declaring_type != null) - return declaring_type.Module; - - return null; - } - } - - IGenericParameterProvider IGenericContext.Type - { - get { return this; } - } - - IGenericParameterProvider IGenericContext.Method - { - get { return null; } - } - - GenericParameterType IGenericParameterProvider.GenericParameterType - { - get { return GenericParameterType.Type; } - } - - public virtual bool HasGenericParameters - { - get { return !Mixin.IsNullOrEmpty(generic_parameters); } - } - - public virtual Collection GenericParameters - { - get - { - if (generic_parameters != null) - return generic_parameters; - - return generic_parameters = new GenericParameterCollection(this); - } - } - - public virtual IMetadataScope Scope - { - get - { - var declaring_type = this.DeclaringType; - if (declaring_type != null) - return declaring_type.Scope; - - return scope; - } - } - - public bool IsNested - { - get { return this.DeclaringType != null; } - } - - public override TypeReference DeclaringType - { - get { return base.DeclaringType; } - set - { - base.DeclaringType = value; - fullname = null; - } - } - - public override string FullName - { - get - { - if (fullname != null) - return fullname; - - if (IsNested) - return fullname = DeclaringType.FullName + "/" + Name; - - if (string.IsNullOrEmpty(@namespace)) - return fullname = Name; - - return fullname = @namespace + "." + Name; - } - } - - public virtual bool IsByReference - { - get { return false; } - } - - public virtual bool IsPointer - { - get { return false; } - } - - public virtual bool IsSentinel - { - get { return false; } - } - - public virtual bool IsArray - { - get { return false; } - } - - public virtual bool IsGenericParameter - { - get { return false; } - } - - public virtual bool IsGenericInstance - { - get { return false; } - } - - public virtual bool IsRequiredModifier - { - get { return false; } - } - - public virtual bool IsOptionalModifier - { - get { return false; } - } - - public virtual bool IsPinned - { - get { return false; } - } - - public virtual bool IsFunctionPointer - { - get { return false; } - } - - public override int GetHashCode() - { - if (hashCode == -1) - hashCode = System.Threading.Interlocked.Add(ref instance_id, 1); - return hashCode; - } - public virtual bool IsPrimitive - { - get { return Mixin.IsPrimitive(etype); } - } - - public virtual MetadataType MetadataType - { - get - { - switch (etype) - { - case ElementType.None: - return IsValueType ? MetadataType.ValueType : MetadataType.Class; - default: - return (MetadataType)etype; - } - } - } - - protected TypeReference(string @namespace, string name) - : base(name) - { - this.@namespace = @namespace ?? string.Empty; - this.token = new MetadataToken(TokenType.TypeRef, 0); - } - - public TypeReference(string @namespace, string name, ModuleDefinition module, IMetadataScope scope) - : this(@namespace, name) - { - this.module = module; - this.scope = scope; - } - - public TypeReference(string @namespace, string name, ModuleDefinition module, IMetadataScope scope, bool valueType) : - this(@namespace, name, module, scope) - { - value_type = valueType; - } - - public virtual TypeReference GetElementType() - { - return this; - } - - public virtual TypeDefinition Resolve() - { - var module = this.Module; - if (module == null) - throw new NotSupportedException(); - - return module.Resolve(this); - } - } - - static partial class Mixin - { - - public static bool IsPrimitive(ElementType self) - { - switch (self) - { - case ElementType.Boolean: - case ElementType.Char: - case ElementType.I: - case ElementType.U: - case ElementType.I1: - case ElementType.U1: - case ElementType.I2: - case ElementType.U2: - case ElementType.I4: - case ElementType.U4: - case ElementType.I8: - case ElementType.U8: - case ElementType.R4: - case ElementType.R8: - return true; - default: - return false; - } - } - - public static bool IsTypeOf(TypeReference self, string @namespace, string name) - { - return self.Name == name - && self.Namespace == @namespace; - } - - public static bool IsTypeSpecification(TypeReference type) - { - switch (type.etype) - { - case ElementType.Array: - case ElementType.ByRef: - case ElementType.CModOpt: - case ElementType.CModReqD: - case ElementType.FnPtr: - case ElementType.GenericInst: - case ElementType.MVar: - case ElementType.Pinned: - case ElementType.Ptr: - case ElementType.SzArray: - case ElementType.Sentinel: - case ElementType.Var: - return true; - } - - return false; - } - - public static TypeDefinition CheckedResolve(TypeReference self) - { - var type = self.Resolve(); - if (type == null) - throw new ResolutionException(self); - - return type; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSpecification.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSpecification.cs deleted file mode 100644 index 54324aa1..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSpecification.cs +++ /dev/null @@ -1,94 +0,0 @@ -// -// TypeSpecification.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using Mono.Cecil.Metadata; - -namespace Mono.Cecil { - - public abstract class TypeSpecification : TypeReference { - - readonly TypeReference element_type; - - public TypeReference ElementType { - get { return element_type; } - } - - public override string Name { - get { return element_type.Name; } - set { throw new NotSupportedException (); } - } - - public override string Namespace { - get { return element_type.Namespace; } - set { throw new NotSupportedException (); } - } - - public override IMetadataScope Scope { - get { return element_type.Scope; } - } - - public override ModuleDefinition Module { - get { return element_type.Module; } - } - - public override string FullName { - get { return element_type.FullName; } - } - - internal override bool ContainsGenericParameter { - get { return element_type.ContainsGenericParameter; } - } - - public override MetadataType MetadataType { - get { return (MetadataType) etype; } - } - - internal TypeSpecification (TypeReference type) - : base (null, null) - { - this.element_type = type; - this.token = new MetadataToken (TokenType.TypeSpec); - } - - public override TypeReference GetElementType () - { - return element_type; - } - } - - static partial class Mixin { - - public static void CheckType (TypeReference type) - { - if (type == null) - throw new ArgumentNullException ("type"); - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSystem.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSystem.cs deleted file mode 100644 index c59962cf..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSystem.cs +++ /dev/null @@ -1,332 +0,0 @@ -// -// TypeSystem.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; - -using Mono.Cecil.Metadata; - -namespace Mono.Cecil -{ - - public abstract class TypeSystem - { - - sealed class CoreTypeSystem : TypeSystem - { - - public CoreTypeSystem(ModuleDefinition module) - : base(module) - { - } - - internal override TypeReference LookupType(string @namespace, string name) - { - var type = LookupTypeDefinition(@namespace, name) ?? LookupTypeForwarded(@namespace, name); - if (type != null) - return type; - - throw new NotSupportedException(); - } - - TypeReference LookupTypeDefinition(string @namespace, string name) - { - var metadata = module.MetadataSystem; - if (metadata.Types == null) - Initialize(module.Types); - - return module.Read(new Row(@namespace, name), (row, reader) => - { - var types = reader.metadata.Types; - - for (int i = 0; i < types.Length; i++) - { - if (types[i] == null) - types[i] = reader.GetTypeDefinition((uint)i + 1); - - var type = types[i]; - - if (type.Name == row.Col2 && type.Namespace == row.Col1) - return type; - } - - return null; - }); - } - - TypeReference LookupTypeForwarded(string @namespace, string name) - { - if (!module.HasExportedTypes) - return null; - - var exported_types = module.ExportedTypes; - for (int i = 0; i < exported_types.Count; i++) - { - var exported_type = exported_types[i]; - - if (exported_type.Name == name && exported_type.Namespace == @namespace) - return exported_type.CreateReference(); - } - - return null; - } - - static void Initialize(object obj) - { - } - } - - sealed class CommonTypeSystem : TypeSystem - { - - AssemblyNameReference corlib; - - public CommonTypeSystem(ModuleDefinition module) - : base(module) - { - } - - internal override TypeReference LookupType(string @namespace, string name) - { - return CreateTypeReference(@namespace, name); - } - - public AssemblyNameReference GetCorlibReference() - { - if (corlib != null) - return corlib; - - const string mscorlib = "mscorlib"; - const string systemruntime = "System.Runtime"; - - var references = module.AssemblyReferences; - - for (int i = 0; i < references.Count; i++) - { - var reference = references[i]; - if (reference.Name == mscorlib || reference.Name == systemruntime) - return corlib = reference; - } - - corlib = new AssemblyNameReference - { - Name = mscorlib, - Version = GetCorlibVersion(), - PublicKeyToken = new byte[] { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 }, - }; - - references.Add(corlib); - - return corlib; - } - - Version GetCorlibVersion() - { - switch (module.Runtime) - { - case TargetRuntime.Net_1_0: - case TargetRuntime.Net_1_1: - return new Version(1, 0, 0, 0); - case TargetRuntime.Net_2_0: - return new Version(2, 0, 0, 0); - case TargetRuntime.Net_4_0: - return new Version(4, 0, 0, 0); - default: - throw new NotSupportedException(); - } - } - - TypeReference CreateTypeReference(string @namespace, string name) - { - return new TypeReference(@namespace, name, module, GetCorlibReference()); - } - } - - readonly ModuleDefinition module; - - TypeReference type_object; - TypeReference type_void; - TypeReference type_bool; - TypeReference type_char; - TypeReference type_sbyte; - TypeReference type_byte; - TypeReference type_int16; - TypeReference type_uint16; - TypeReference type_int32; - TypeReference type_uint32; - TypeReference type_int64; - TypeReference type_uint64; - TypeReference type_single; - TypeReference type_double; - TypeReference type_intptr; - TypeReference type_uintptr; - TypeReference type_string; - TypeReference type_typedref; - - TypeSystem(ModuleDefinition module) - { - this.module = module; - } - - internal static TypeSystem CreateTypeSystem(ModuleDefinition module) - { - if (Mixin.IsCorlib(module)) - return new CoreTypeSystem(module); - - return new CommonTypeSystem(module); - } - - internal abstract TypeReference LookupType(string @namespace, string name); - - TypeReference LookupSystemType(ref TypeReference typeRef, string name, ElementType element_type) - { - lock (module.SyncRoot) - { - if (typeRef != null) - return typeRef; - var type = LookupType("System", name); - type.etype = element_type; - return typeRef = type; - } - } - - TypeReference LookupSystemValueType(ref TypeReference typeRef, string name, ElementType element_type) - { - lock (module.SyncRoot) - { - if (typeRef != null) - return typeRef; - var type = LookupType("System", name); - type.etype = element_type; - type.IsValueType = true; - return typeRef = type; - } - } - - public IMetadataScope Corlib - { - get - { - var common = this as CommonTypeSystem; - if (common == null) - return module; - - return common.GetCorlibReference(); - } - } - - public TypeReference Object - { - get { return type_object ?? (LookupSystemType(ref type_object, "Object", ElementType.Object)); } - } - - public TypeReference Void - { - get { return type_void ?? (LookupSystemType(ref type_void, "Void", ElementType.Void)); } - } - - public TypeReference Boolean - { - get { return type_bool ?? (LookupSystemValueType(ref type_bool, "Boolean", ElementType.Boolean)); } - } - - public TypeReference Char - { - get { return type_char ?? (LookupSystemValueType(ref type_char, "Char", ElementType.Char)); } - } - - public TypeReference SByte - { - get { return type_sbyte ?? (LookupSystemValueType(ref type_sbyte, "SByte", ElementType.I1)); } - } - - public TypeReference Byte - { - get { return type_byte ?? (LookupSystemValueType(ref type_byte, "Byte", ElementType.U1)); } - } - - public TypeReference Int16 - { - get { return type_int16 ?? (LookupSystemValueType(ref type_int16, "Int16", ElementType.I2)); } - } - - public TypeReference UInt16 - { - get { return type_uint16 ?? (LookupSystemValueType(ref type_uint16, "UInt16", ElementType.U2)); } - } - - public TypeReference Int32 - { - get { return type_int32 ?? (LookupSystemValueType(ref type_int32, "Int32", ElementType.I4)); } - } - - public TypeReference UInt32 - { - get { return type_uint32 ?? (LookupSystemValueType(ref type_uint32, "UInt32", ElementType.U4)); } - } - - public TypeReference Int64 - { - get { return type_int64 ?? (LookupSystemValueType(ref type_int64, "Int64", ElementType.I8)); } - } - - public TypeReference UInt64 - { - get { return type_uint64 ?? (LookupSystemValueType(ref type_uint64, "UInt64", ElementType.U8)); } - } - - public TypeReference Single - { - get { return type_single ?? (LookupSystemValueType(ref type_single, "Single", ElementType.R4)); } - } - - public TypeReference Double - { - get { return type_double ?? (LookupSystemValueType(ref type_double, "Double", ElementType.R8)); } - } - - public TypeReference IntPtr - { - get { return type_intptr ?? (LookupSystemValueType(ref type_intptr, "IntPtr", ElementType.I)); } - } - - public TypeReference UIntPtr - { - get { return type_uintptr ?? (LookupSystemValueType(ref type_uintptr, "UIntPtr", ElementType.U)); } - } - - public TypeReference String - { - get { return type_string ?? (LookupSystemType(ref type_string, "String", ElementType.String)); } - } - - public TypeReference TypedReference - { - get { return type_typedref ?? (LookupSystemValueType(ref type_typedref, "TypedReference", ElementType.TypedByRef)); } - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/VariantType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/VariantType.cs deleted file mode 100644 index 76562f6e..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Cecil/VariantType.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -// VariantType.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -namespace Mono.Cecil { - - public enum VariantType { - None = 0, - I2 = 2, - I4 = 3, - R4 = 4, - R8 = 5, - CY = 6, - Date = 7, - BStr = 8, - Dispatch = 9, - Error = 10, - Bool = 11, - Variant = 12, - Unknown = 13, - Decimal = 14, - I1 = 16, - UI1 = 17, - UI2 = 18, - UI4 = 19, - Int = 22, - UInt = 23 - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoConvert.cs b/Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoConvert.cs deleted file mode 100644 index e69de29b..00000000 diff --git a/Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoService.cs b/Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoService.cs deleted file mode 100644 index 12590628..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoService.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// CryptoService.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.IO; -using System.Reflection; -using System.Security.Cryptography; - diff --git a/Mono.Cecil.20/MonoCecil/Mono/Actions.cs b/Mono.Cecil.20/MonoCecil/Mono/Actions.cs deleted file mode 100644 index e64c4fb1..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono/Actions.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Actions.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -#if !NET_3_5 && !NET_4_0 - -namespace Mono { - //delegate void Action (); - delegate void Action (T1 arg1, T2 arg2); - //delegate void Action (T1 arg1, T2 arg2, T3 arg3); - //delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4); -} - -#endif diff --git a/Mono.Cecil.20/MonoCecil/Mono/Empty.cs b/Mono.Cecil.20/MonoCecil/Mono/Empty.cs deleted file mode 100644 index db49b5e3..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono/Empty.cs +++ /dev/null @@ -1,53 +0,0 @@ -// -// Empty.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using Mono.Collections.Generic; - -namespace Mono { - - static class Empty { - - public static readonly T [] Array = new T [0]; - } -} - -namespace Mono.Cecil { - - static partial class Mixin { - - public static bool IsNullOrEmpty (T [] self) - { - return self == null || self.Length == 0; - } - - public static bool IsNullOrEmpty (Collection self) - { - return self == null || self.size == 0; - } - } -} diff --git a/Mono.Cecil.20/MonoCecil/Mono/Funcs.cs b/Mono.Cecil.20/MonoCecil/Mono/Funcs.cs deleted file mode 100644 index 22ac26ee..00000000 --- a/Mono.Cecil.20/MonoCecil/Mono/Funcs.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Funcs.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -#if !NET_3_5 && !NET_4_0 - -namespace Mono { - delegate TResult Func (); - delegate TResult Func (T arg1); - delegate TResult Func (T1 arg1, T2 arg2); - //delegate TResult Func (T1 arg1, T2 arg2, T3 arg3); - //delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4); -} - -#endif diff --git a/Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj b/Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj index bac84da7..310016bb 100644 --- a/Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj +++ b/Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj @@ -1,85 +1,24 @@ - - - + + - Debug - AnyCPU - {86F36240-E07C-4840-9C8B-9CD94C03EC62} - Library - Properties + {8559DD7F-A16F-46D0-A05A-9139FAEBA8FD} Mono.Cecil.Mdb Mono.Cecil.Mdb - v3.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {d3785d8b-4d85-4546-8763-47fc848c13e0} - Mono.Cecil.20 + + {D68133BD-1E63-496E-9EDE-4FBDBF77B486} + Mono.Cecil - + + + - - - \ No newline at end of file + + + + $(DefineConstants);CECIL + + diff --git a/Mono.Cecil.Mdb/Mono.Cecil.Mdb/AssemblyInfo.cs b/Mono.Cecil.Mdb/Mono.Cecil.Mdb/AssemblyInfo.cs new file mode 100644 index 00000000..12f9bb63 --- /dev/null +++ b/Mono.Cecil.Mdb/Mono.Cecil.Mdb/AssemblyInfo.cs @@ -0,0 +1,16 @@ +// +// 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.Reflection; + +[assembly: AssemblyTitle ("Mono.Cecil.Mdb")] + +[assembly: CLSCompliant (false)] diff --git a/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbReader.cs b/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbReader.cs new file mode 100644 index 00000000..66a72259 --- /dev/null +++ b/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbReader.cs @@ -0,0 +1,211 @@ +// +// 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.Cecil.Cil; +using Mono.Collections.Generic; +using Mono.CompilerServices.SymbolWriter; + +namespace Mono.Cecil.Mdb { + + public sealed class MdbReaderProvider : ISymbolReaderProvider { + + public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + return new MdbReader (module, MonoSymbolFile.ReadSymbolFile (Mixin.GetMdbFileName (fileName), module.Mvid)); + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + + var file = MonoSymbolFile.ReadSymbolFile (symbolStream); + if (module.Mvid != file.Guid) { + var file_stream = symbolStream as FileStream; + if (file_stream != null) + throw new MonoSymbolFileException ("Symbol file `{0}' does not match assembly", file_stream.Name); + + throw new MonoSymbolFileException ("Symbol file from stream does not match assembly"); + } + return new MdbReader (module, file); + } + } + + public sealed class MdbReader : ISymbolReader { + + readonly ModuleDefinition module; + readonly MonoSymbolFile symbol_file; + readonly Dictionary documents; + + public MdbReader (ModuleDefinition module, MonoSymbolFile symFile) + { + this.module = module; + this.symbol_file = symFile; + this.documents = new Dictionary (); + } + +#if !READ_ONLY + public ISymbolWriterProvider GetWriterProvider () + { + return new MdbWriterProvider (); + } +#endif + + public bool ProcessDebugHeader (ImageDebugHeader header) + { + return symbol_file.Guid == module.Mvid; + } + + public MethodDebugInformation Read (MethodDefinition method) + { + var method_token = method.MetadataToken; + var entry = symbol_file.GetMethodByToken (method_token.ToInt32 ()); + if (entry == null) + return null; + + var info = new MethodDebugInformation (method); + + var scopes = ReadScopes (entry, info); + ReadLineNumbers (entry, info); + ReadLocalVariables (entry, scopes); + + return info; + } + + static void ReadLocalVariables (MethodEntry entry, ScopeDebugInformation [] scopes) + { + var locals = entry.GetLocals (); + + foreach (var local in locals) { + var variable = new VariableDebugInformation (local.Index, local.Name); + + var index = local.BlockIndex; + if (index < 0 || index >= scopes.Length) + continue; + + var scope = scopes [index]; + if (scope == null) + continue; + + scope.Variables.Add (variable); + } + } + + void ReadLineNumbers (MethodEntry entry, MethodDebugInformation info) + { + var table = entry.GetLineNumberTable (); + + info.sequence_points = new Collection (table.LineNumbers.Length); + + for (var i = 0; i < table.LineNumbers.Length; i++) { + var line = table.LineNumbers [i]; + if (i > 0 && table.LineNumbers [i - 1].Offset == line.Offset) + continue; + + info.sequence_points.Add (LineToSequencePoint (line)); + } + } + + Document GetDocument (SourceFileEntry file) + { + var file_name = file.FileName; + + Document document; + if (documents.TryGetValue (file_name, out document)) + return document; + + document = new Document (file_name) { + Hash = file.Checksum, + }; + + documents.Add (file_name, document); + + return document; + } + + static ScopeDebugInformation [] ReadScopes (MethodEntry entry, MethodDebugInformation info) + { + var blocks = entry.GetCodeBlocks (); + var scopes = new ScopeDebugInformation [blocks.Length + 1]; + + info.scope = scopes [0] = new ScopeDebugInformation { + Start = new InstructionOffset (0), + End = new InstructionOffset (info.code_size), + }; + + foreach (var block in blocks) { + if (block.BlockType != CodeBlockEntry.Type.Lexical && block.BlockType != CodeBlockEntry.Type.CompilerGenerated) + continue; + + var scope = new ScopeDebugInformation (); + scope.Start = new InstructionOffset (block.StartOffset); + scope.End = new InstructionOffset (block.EndOffset); + + scopes [block.Index + 1] = scope; + + if (!AddScope (info.scope.Scopes, scope)) + info.scope.Scopes.Add (scope); + } + + return scopes; + } + + static bool AddScope (Collection scopes, ScopeDebugInformation 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) { + sub_scope.Scopes.Add (scope); + return true; + } + } + + return false; + } + + SequencePoint LineToSequencePoint (LineNumberEntry line) + { + var source = symbol_file.GetSourceFile (line.File); + return new SequencePoint (line.Offset, GetDocument (source)) { + StartLine = line.Row, + EndLine = line.EndRow, + StartColumn = line.Column, + EndColumn = line.EndColumn, + }; + } + + public void Dispose () + { + symbol_file.Dispose (); + } + } + + static class MethodEntryExtensions { + + public static bool HasColumnInfo (this MethodEntry entry) + { + return (entry.MethodFlags & MethodEntry.Flags.ColumnsInfoIncluded) != 0; + } + + public static bool HasEndInfo (this MethodEntry entry) + { + return (entry.MethodFlags & MethodEntry.Flags.EndInfoIncluded) != 0; + } + } +} diff --git a/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbWriter.cs b/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbWriter.cs new file mode 100644 index 00000000..8c3dbe3e --- /dev/null +++ b/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbWriter.cs @@ -0,0 +1,215 @@ +// +// 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.Cecil.Cil; +using Mono.Collections.Generic; +using Mono.CompilerServices.SymbolWriter; + +namespace Mono.Cecil.Mdb { + +#if !READ_ONLY + public sealed class MdbWriterProvider : ISymbolWriterProvider { + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + return new MdbWriter (module.Mvid, fileName); + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + throw new NotImplementedException (); + } + } + + public sealed class MdbWriter : ISymbolWriter { + + readonly Guid mvid; + readonly MonoSymbolWriter writer; + readonly Dictionary source_files; + + public MdbWriter (Guid mvid, string assembly) + { + this.mvid = mvid; + this.writer = new MonoSymbolWriter (assembly); + this.source_files = new Dictionary (); + } + + public ISymbolReaderProvider GetReaderProvider () + { + return new MdbReaderProvider (); + } + + SourceFile GetSourceFile (Document document) + { + var url = document.Url; + + SourceFile source_file; + if (source_files.TryGetValue (url, out source_file)) + return source_file; + + var entry = writer.DefineDocument (url, null, document.Hash != null && document.Hash.Length == 16 ? document.Hash : null); + var compile_unit = writer.DefineCompilationUnit (entry); + + source_file = new SourceFile (compile_unit, entry); + source_files.Add (url, source_file); + return source_file; + } + + 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 < sequencePoints.Count; i++) { + var sequence_point = sequencePoints [i]; + offsets [i] = sequence_point.Offset; + + if (source_file == null) + source_file = GetSourceFile (sequence_point.Document); + + startRows [i] = sequence_point.StartLine; + endRows [i] = sequence_point.EndLine; + startCols [i] = sequence_point.StartColumn; + endCols [i] = sequence_point.EndColumn; + } + + file = source_file; + } + + public void Write (MethodDebugInformation info) + { + var method = new SourceMethod (info.method); + + var sequence_points = info.SequencePoints; + int count = sequence_points.Count; + if (count == 0) + return; + + var offsets = new int [count]; + var start_rows = new int [count]; + var end_rows = new int [count]; + var start_cols = new int [count]; + var end_cols = new int [count]; + + SourceFile file; + Populate (sequence_points, offsets, start_rows, end_rows, start_cols, end_cols, out file); + + var builder = writer.OpenMethod (file.CompilationUnit, 0, method); + + for (int i = 0; i < count; i++) { + builder.MarkSequencePoint ( + offsets [i], + file.CompilationUnit.SourceFile, + start_rows [i], + start_cols [i], + end_rows [i], + end_cols [i], + false); + } + + if (info.scope != null) + WriteRootScope (info.scope, info); + + writer.CloseMethod (); + } + + void WriteRootScope (ScopeDebugInformation scope, MethodDebugInformation info) + { + WriteScopeVariables (scope); + + if (scope.HasScopes) + WriteScopes (scope.Scopes, info); + } + + void WriteScope (ScopeDebugInformation scope, MethodDebugInformation info) + { + writer.OpenScope (scope.Start.Offset); + + WriteScopeVariables (scope); + + if (scope.HasScopes) + WriteScopes (scope.Scopes, info); + + writer.CloseScope (scope.End.IsEndOfMethod ? info.code_size : scope.End.Offset); + } + + void WriteScopes (Collection scopes, MethodDebugInformation info) + { + for (int i = 0; i < scopes.Count; i++) + WriteScope (scopes [i], info); + } + + 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); + } + + public ImageDebugHeader GetDebugHeader () + { + return new ImageDebugHeader (); + } + + public void Dispose () + { + writer.WriteSymbolFile (mvid); + } + + class SourceFile : ISourceFile { + + readonly CompileUnitEntry compilation_unit; + readonly SourceFileEntry entry; + + public SourceFileEntry Entry { + get { return entry; } + } + + public CompileUnitEntry CompilationUnit { + get { return compilation_unit; } + } + + public SourceFile (CompileUnitEntry comp_unit, SourceFileEntry entry) + { + this.compilation_unit = comp_unit; + this.entry = entry; + } + } + + class SourceMethod : IMethodDef { + + readonly MethodDefinition method; + + public string Name { + get { return method.Name; } + } + + public int Token { + get { return method.MetadataToken.ToInt32 (); } + } + + public SourceMethod (MethodDefinition method) + { + this.method = method; + } + } + } +#endif +} diff --git a/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs b/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs new file mode 100644 index 00000000..2b6c3a6a --- /dev/null +++ b/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs @@ -0,0 +1,643 @@ +// +// MonoSymbolFile.cs +// +// Authors: +// Martin Baulig (martin@ximian.com) +// Marek Safar (marek.safar@gmail.com) +// +// (C) 2003 Ximian, Inc. http://www.ximian.com +// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com) +// +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Reflection; +using System.Collections.Generic; +using System.IO; + +namespace Mono.CompilerServices.SymbolWriter +{ + public class MonoSymbolFileException : Exception + { + public MonoSymbolFileException () + : base () + { } + + public MonoSymbolFileException (string message, params object[] args) + : base (String.Format (message, args)) + { + } + + public MonoSymbolFileException (string message, Exception innerException) + : base (message, innerException) + { + } + } + + sealed class MyBinaryWriter : BinaryWriter + { + public MyBinaryWriter (Stream stream) + : base (stream) + { } + + public void WriteLeb128 (int value) + { + base.Write7BitEncodedInt (value); + } + } + + internal class MyBinaryReader : BinaryReader + { + public MyBinaryReader (Stream stream) + : base (stream) + { } + + public int ReadLeb128 () + { + return base.Read7BitEncodedInt (); + } + + public string ReadString (int offset) + { + long old_pos = BaseStream.Position; + BaseStream.Position = offset; + + string text = ReadString (); + + BaseStream.Position = old_pos; + return text; + } + } + + public interface ISourceFile + { + SourceFileEntry Entry { + get; + } + } + + public interface ICompileUnit + { + CompileUnitEntry Entry { + get; + } + } + + public interface IMethodDef + { + string Name { + get; + } + + int Token { + get; + } + } + + public class MonoSymbolFile : IDisposable + { + List methods = new List (); + List sources = new List (); + List comp_units = new List (); + Dictionary anonymous_scopes; + + OffsetTable ot; + int last_type_index; + int last_method_index; + int last_namespace_index; + + public readonly int MajorVersion = OffsetTable.MajorVersion; + public readonly int MinorVersion = OffsetTable.MinorVersion; + + public int NumLineNumbers; + + public MonoSymbolFile () + { + ot = new OffsetTable (); + } + + public int AddSource (SourceFileEntry source) + { + sources.Add (source); + return sources.Count; + } + + public int AddCompileUnit (CompileUnitEntry entry) + { + comp_units.Add (entry); + return comp_units.Count; + } + + public void AddMethod (MethodEntry entry) + { + methods.Add (entry); + } + + public MethodEntry DefineMethod (CompileUnitEntry comp_unit, int token, + ScopeVariable[] scope_vars, LocalVariableEntry[] locals, + LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, + string real_name, MethodEntry.Flags flags, + int namespace_id) + { + if (reader != null) + throw new InvalidOperationException (); + + MethodEntry method = new MethodEntry ( + this, comp_unit, token, scope_vars, locals, lines, code_blocks, + real_name, flags, namespace_id); + AddMethod (method); + return method; + } + + internal void DefineAnonymousScope (int id) + { + if (reader != null) + throw new InvalidOperationException (); + + if (anonymous_scopes == null) + anonymous_scopes = new Dictionary (); + + anonymous_scopes.Add (id, new AnonymousScopeEntry (id)); + } + + internal void DefineCapturedVariable (int scope_id, string name, string captured_name, + CapturedVariable.CapturedKind kind) + { + if (reader != null) + throw new InvalidOperationException (); + + AnonymousScopeEntry scope = anonymous_scopes [scope_id]; + scope.AddCapturedVariable (name, captured_name, kind); + } + + internal void DefineCapturedScope (int scope_id, int id, string captured_name) + { + if (reader != null) + throw new InvalidOperationException (); + + AnonymousScopeEntry scope = anonymous_scopes [scope_id]; + scope.AddCapturedScope (id, captured_name); + } + + internal int GetNextTypeIndex () + { + return ++last_type_index; + } + + internal int GetNextMethodIndex () + { + return ++last_method_index; + } + + internal int GetNextNamespaceIndex () + { + return ++last_namespace_index; + } + + void Write (MyBinaryWriter bw, Guid guid) + { + // Magic number and file version. + bw.Write (OffsetTable.Magic); + bw.Write (MajorVersion); + bw.Write (MinorVersion); + + bw.Write (guid.ToByteArray ()); + + // + // Offsets of file sections; we must write this after we're done + // writing the whole file, so we just reserve the space for it here. + // + long offset_table_offset = bw.BaseStream.Position; + ot.Write (bw, MajorVersion, MinorVersion); + + // + // Sort the methods according to their tokens and update their index. + // + methods.Sort (); + for (int i = 0; i < methods.Count; i++) + methods [i].Index = i + 1; + + // + // Write data sections. + // + ot.DataSectionOffset = (int) bw.BaseStream.Position; + foreach (SourceFileEntry source in sources) + source.WriteData (bw); + foreach (CompileUnitEntry comp_unit in comp_units) + comp_unit.WriteData (bw); + foreach (MethodEntry method in methods) + method.WriteData (this, bw); + ot.DataSectionSize = (int) bw.BaseStream.Position - ot.DataSectionOffset; + + // + // Write the method index table. + // + ot.MethodTableOffset = (int) bw.BaseStream.Position; + for (int i = 0; i < methods.Count; i++) { + MethodEntry entry = methods [i]; + entry.Write (bw); + } + ot.MethodTableSize = (int) bw.BaseStream.Position - ot.MethodTableOffset; + + // + // Write source table. + // + ot.SourceTableOffset = (int) bw.BaseStream.Position; + for (int i = 0; i < sources.Count; i++) { + SourceFileEntry source = sources [i]; + source.Write (bw); + } + ot.SourceTableSize = (int) bw.BaseStream.Position - ot.SourceTableOffset; + + // + // Write compilation unit table. + // + ot.CompileUnitTableOffset = (int) bw.BaseStream.Position; + for (int i = 0; i < comp_units.Count; i++) { + CompileUnitEntry unit = comp_units [i]; + unit.Write (bw); + } + ot.CompileUnitTableSize = (int) bw.BaseStream.Position - ot.CompileUnitTableOffset; + + // + // Write anonymous scope table. + // + ot.AnonymousScopeCount = anonymous_scopes != null ? anonymous_scopes.Count : 0; + ot.AnonymousScopeTableOffset = (int) bw.BaseStream.Position; + if (anonymous_scopes != null) { + foreach (AnonymousScopeEntry scope in anonymous_scopes.Values) + scope.Write (bw); + } + ot.AnonymousScopeTableSize = (int) bw.BaseStream.Position - ot.AnonymousScopeTableOffset; + + // + // Fixup offset table. + // + ot.TypeCount = last_type_index; + ot.MethodCount = methods.Count; + ot.SourceCount = sources.Count; + ot.CompileUnitCount = comp_units.Count; + + // + // Write offset table. + // + ot.TotalFileSize = (int) bw.BaseStream.Position; + bw.Seek ((int) offset_table_offset, SeekOrigin.Begin); + ot.Write (bw, MajorVersion, MinorVersion); + bw.Seek (0, SeekOrigin.End); + +#if false + Console.WriteLine ("TOTAL: {0} line numbes, {1} bytes, extended {2} bytes, " + + "{3} methods.", NumLineNumbers, LineNumberSize, + ExtendedLineNumberSize, methods.Count); +#endif + } + + public void CreateSymbolFile (Guid guid, FileStream fs) + { + if (reader != null) + throw new InvalidOperationException (); + + Write (new MyBinaryWriter (fs), guid); + } + + MyBinaryReader reader; + Dictionary source_file_hash; + Dictionary compile_unit_hash; + + List method_list; + Dictionary method_token_hash; + Dictionary source_name_hash; + + Guid guid; + + MonoSymbolFile (Stream stream) + { + reader = new MyBinaryReader (stream); + + try { + long magic = reader.ReadInt64 (); + int major_version = reader.ReadInt32 (); + int minor_version = reader.ReadInt32 (); + + if (magic != OffsetTable.Magic) + throw new MonoSymbolFileException ("Symbol file is not a valid"); + if (major_version != OffsetTable.MajorVersion) + throw new MonoSymbolFileException ( + "Symbol file has version {0} but expected {1}", major_version, OffsetTable.MajorVersion); + if (minor_version != OffsetTable.MinorVersion) + throw new MonoSymbolFileException ("Symbol file has version {0}.{1} but expected {2}.{3}", + major_version, minor_version, + OffsetTable.MajorVersion, OffsetTable.MinorVersion); + + MajorVersion = major_version; + MinorVersion = minor_version; + guid = new Guid (reader.ReadBytes (16)); + + ot = new OffsetTable (reader, major_version, minor_version); + } catch (Exception e) { + throw new MonoSymbolFileException ("Cannot read symbol file", e); + } + + source_file_hash = new Dictionary (); + compile_unit_hash = new Dictionary (); + } + +#if !NET_CORE + public static MonoSymbolFile ReadSymbolFile (Assembly assembly) + { + string filename = assembly.Location; + string name = filename + ".mdb"; + + Module[] modules = assembly.GetModules (); + Guid assembly_guid = modules[0].ModuleVersionId; + + return ReadSymbolFile (name, assembly_guid); + } +#endif + + public static MonoSymbolFile ReadSymbolFile (string mdbFilename) + { + return ReadSymbolFile (new FileStream (mdbFilename, FileMode.Open, FileAccess.Read)); + } + + public static MonoSymbolFile ReadSymbolFile (string mdbFilename, Guid assemblyGuid) + { + var sf = ReadSymbolFile (mdbFilename); + if (assemblyGuid != sf.guid) + throw new MonoSymbolFileException ("Symbol file `{0}' does not match assembly", mdbFilename); + + return sf; + } + + public static MonoSymbolFile ReadSymbolFile (Stream stream) + { + return new MonoSymbolFile (stream); + } + + public int CompileUnitCount { + get { return ot.CompileUnitCount; } + } + + public int SourceCount { + get { return ot.SourceCount; } + } + + public int MethodCount { + get { return ot.MethodCount; } + } + + public int TypeCount { + get { return ot.TypeCount; } + } + + public int AnonymousScopeCount { + get { return ot.AnonymousScopeCount; } + } + + public int NamespaceCount { + get { return last_namespace_index; } + } + + public Guid Guid { + get { return guid; } + } + + public OffsetTable OffsetTable { + get { return ot; } + } + + internal int LineNumberCount = 0; + internal int LocalCount = 0; + internal int StringSize = 0; + + internal int LineNumberSize = 0; + internal int ExtendedLineNumberSize = 0; + + public SourceFileEntry GetSourceFile (int index) + { + if ((index < 1) || (index > ot.SourceCount)) + throw new ArgumentException (); + if (reader == null) + throw new InvalidOperationException (); + + lock (this) { + SourceFileEntry source; + if (source_file_hash.TryGetValue (index, out source)) + return source; + + long old_pos = reader.BaseStream.Position; + + reader.BaseStream.Position = ot.SourceTableOffset + + SourceFileEntry.Size * (index - 1); + source = new SourceFileEntry (this, reader); + source_file_hash.Add (index, source); + + reader.BaseStream.Position = old_pos; + return source; + } + } + + public SourceFileEntry[] Sources { + get { + if (reader == null) + throw new InvalidOperationException (); + + SourceFileEntry[] retval = new SourceFileEntry [SourceCount]; + for (int i = 0; i < SourceCount; i++) + retval [i] = GetSourceFile (i + 1); + return retval; + } + } + + public CompileUnitEntry GetCompileUnit (int index) + { + if ((index < 1) || (index > ot.CompileUnitCount)) + throw new ArgumentException (); + if (reader == null) + throw new InvalidOperationException (); + + lock (this) { + CompileUnitEntry unit; + if (compile_unit_hash.TryGetValue (index, out unit)) + return unit; + + long old_pos = reader.BaseStream.Position; + + reader.BaseStream.Position = ot.CompileUnitTableOffset + + CompileUnitEntry.Size * (index - 1); + unit = new CompileUnitEntry (this, reader); + compile_unit_hash.Add (index, unit); + + reader.BaseStream.Position = old_pos; + return unit; + } + } + + public CompileUnitEntry[] CompileUnits { + get { + if (reader == null) + throw new InvalidOperationException (); + + CompileUnitEntry[] retval = new CompileUnitEntry [CompileUnitCount]; + for (int i = 0; i < CompileUnitCount; i++) + retval [i] = GetCompileUnit (i + 1); + return retval; + } + } + + void read_methods () + { + lock (this) { + if (method_token_hash != null) + return; + + method_token_hash = new Dictionary (); + method_list = new List (); + + long old_pos = reader.BaseStream.Position; + reader.BaseStream.Position = ot.MethodTableOffset; + + for (int i = 0; i < MethodCount; i++) { + MethodEntry entry = new MethodEntry (this, reader, i + 1); + method_token_hash.Add (entry.Token, entry); + method_list.Add (entry); + } + + reader.BaseStream.Position = old_pos; + } + } + + public MethodEntry GetMethodByToken (int token) + { + if (reader == null) + throw new InvalidOperationException (); + + lock (this) { + read_methods (); + MethodEntry me; + method_token_hash.TryGetValue (token, out me); + return me; + } + } + + public MethodEntry GetMethod (int index) + { + if ((index < 1) || (index > ot.MethodCount)) + throw new ArgumentException (); + if (reader == null) + throw new InvalidOperationException (); + + lock (this) { + read_methods (); + return method_list [index - 1]; + } + } + + public MethodEntry[] Methods { + get { + if (reader == null) + throw new InvalidOperationException (); + + lock (this) { + read_methods (); + MethodEntry[] retval = new MethodEntry [MethodCount]; + method_list.CopyTo (retval, 0); + return retval; + } + } + } + + public int FindSource (string file_name) + { + if (reader == null) + throw new InvalidOperationException (); + + lock (this) { + if (source_name_hash == null) { + source_name_hash = new Dictionary (); + + for (int i = 0; i < ot.SourceCount; i++) { + SourceFileEntry source = GetSourceFile (i + 1); + source_name_hash.Add (source.FileName, i); + } + } + + int value; + if (!source_name_hash.TryGetValue (file_name, out value)) + return -1; + return value; + } + } + + public AnonymousScopeEntry GetAnonymousScope (int id) + { + if (reader == null) + throw new InvalidOperationException (); + + AnonymousScopeEntry scope; + lock (this) { + if (anonymous_scopes != null) { + anonymous_scopes.TryGetValue (id, out scope); + return scope; + } + + anonymous_scopes = new Dictionary (); + reader.BaseStream.Position = ot.AnonymousScopeTableOffset; + for (int i = 0; i < ot.AnonymousScopeCount; i++) { + scope = new AnonymousScopeEntry (reader); + anonymous_scopes.Add (scope.ID, scope); + } + + return anonymous_scopes [id]; + } + } + + internal MyBinaryReader BinaryReader { + get { + if (reader == null) + throw new InvalidOperationException (); + + return reader; + } + } + + public void Dispose () + { + Dispose (true); + } + + protected virtual void Dispose (bool disposing) + { + if (disposing) { + if (reader != null) { +#if NET_CORE + reader.Dispose (); +#else + reader.Close (); +#endif + reader = null; + } + } + } + } +} diff --git a/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs b/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs new file mode 100644 index 00000000..0eec10fd --- /dev/null +++ b/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs @@ -0,0 +1,1446 @@ +// +// Mono.CSharp.Debugger/MonoSymbolTable.cs +// +// Author: +// Martin Baulig (martin@ximian.com) +// +// (C) 2002 Ximian, Inc. http://www.ximian.com +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Security.Cryptography; +using System.Collections.Generic; +using System.Text; +using System.IO; + +// +// Parts which are actually written into the symbol file are marked with +// +// #region This is actually written to the symbol file +// #endregion +// +// Please do not modify these regions without previously talking to me. +// +// All changes to the file format must be synchronized in several places: +// +// a) The fields in these regions (and their order) must match the actual +// contents of the symbol file. +// +// This helps people to understand the symbol file format without reading +// too much source code, ie. you look at the appropriate region and then +// you know what's actually in the file. +// +// It is also required to help me enforce b). +// +// b) The regions must be kept in sync with the unmanaged code in +// mono/metadata/debug-mono-symfile.h +// +// When making changes to the file format, you must also increase two version +// numbers: +// +// i) OffsetTable.Version in this file. +// ii) MONO_SYMBOL_FILE_VERSION in mono/metadata/debug-mono-symfile.h +// +// After doing so, recompile everything, including the debugger. Symbol files +// with different versions are incompatible to each other and the debugger and +// the runtime enfore this, so you need to recompile all your assemblies after +// changing the file format. +// + +namespace Mono.CompilerServices.SymbolWriter +{ + public class OffsetTable + { + public const int MajorVersion = 50; + public const int MinorVersion = 0; + public const long Magic = 0x45e82623fd7fa614; + + #region This is actually written to the symbol file + public int TotalFileSize; + public int DataSectionOffset; + public int DataSectionSize; + public int CompileUnitCount; + public int CompileUnitTableOffset; + public int CompileUnitTableSize; + public int SourceCount; + public int SourceTableOffset; + public int SourceTableSize; + public int MethodCount; + public int MethodTableOffset; + public int MethodTableSize; + public int TypeCount; + public int AnonymousScopeCount; + public int AnonymousScopeTableOffset; + public int AnonymousScopeTableSize; + + [Flags] + public enum Flags + { + IsAspxSource = 1, + WindowsFileNames = 2 + } + + public Flags FileFlags; + + public int LineNumberTable_LineBase = LineNumberTable.Default_LineBase; + public int LineNumberTable_LineRange = LineNumberTable.Default_LineRange; + public int LineNumberTable_OpcodeBase = LineNumberTable.Default_OpcodeBase; + #endregion + + internal OffsetTable () + { +#if !NET_CORE + int platform = (int) Environment.OSVersion.Platform; + if ((platform != 4) && (platform != 128)) + FileFlags |= Flags.WindowsFileNames; +#endif + } + + internal OffsetTable (BinaryReader reader, int major_version, int minor_version) + { + TotalFileSize = reader.ReadInt32 (); + DataSectionOffset = reader.ReadInt32 (); + DataSectionSize = reader.ReadInt32 (); + CompileUnitCount = reader.ReadInt32 (); + CompileUnitTableOffset = reader.ReadInt32 (); + CompileUnitTableSize = reader.ReadInt32 (); + SourceCount = reader.ReadInt32 (); + SourceTableOffset = reader.ReadInt32 (); + SourceTableSize = reader.ReadInt32 (); + MethodCount = reader.ReadInt32 (); + MethodTableOffset = reader.ReadInt32 (); + MethodTableSize = reader.ReadInt32 (); + TypeCount = reader.ReadInt32 (); + + AnonymousScopeCount = reader.ReadInt32 (); + AnonymousScopeTableOffset = reader.ReadInt32 (); + AnonymousScopeTableSize = reader.ReadInt32 (); + + LineNumberTable_LineBase = reader.ReadInt32 (); + LineNumberTable_LineRange = reader.ReadInt32 (); + LineNumberTable_OpcodeBase = reader.ReadInt32 (); + + FileFlags = (Flags) reader.ReadInt32 (); + } + + internal void Write (BinaryWriter bw, int major_version, int minor_version) + { + bw.Write (TotalFileSize); + bw.Write (DataSectionOffset); + bw.Write (DataSectionSize); + bw.Write (CompileUnitCount); + bw.Write (CompileUnitTableOffset); + bw.Write (CompileUnitTableSize); + bw.Write (SourceCount); + bw.Write (SourceTableOffset); + bw.Write (SourceTableSize); + bw.Write (MethodCount); + bw.Write (MethodTableOffset); + bw.Write (MethodTableSize); + bw.Write (TypeCount); + + bw.Write (AnonymousScopeCount); + bw.Write (AnonymousScopeTableOffset); + bw.Write (AnonymousScopeTableSize); + + bw.Write (LineNumberTable_LineBase); + bw.Write (LineNumberTable_LineRange); + bw.Write (LineNumberTable_OpcodeBase); + + bw.Write ((int) FileFlags); + } + + public override string ToString () + { + return String.Format ( + "OffsetTable [{0} - {1}:{2} - {3}:{4}:{5} - {6}:{7}:{8} - {9}]", + TotalFileSize, DataSectionOffset, DataSectionSize, SourceCount, + SourceTableOffset, SourceTableSize, MethodCount, MethodTableOffset, + MethodTableSize, TypeCount); + } + } + + public class LineNumberEntry + { + #region This is actually written to the symbol file + public readonly int Row; + public int Column; + public int EndRow, EndColumn; + public readonly int File; + public readonly int Offset; + public readonly bool IsHidden; // Obsolete is never used + #endregion + + public sealed class LocationComparer : IComparer + { + public static readonly LocationComparer Default = new LocationComparer (); + + public int Compare (LineNumberEntry l1, LineNumberEntry l2) + { + return l1.Row == l2.Row ? + l1.Column.CompareTo (l2.Column) : + l1.Row.CompareTo (l2.Row); + } + } + + public static readonly LineNumberEntry Null = new LineNumberEntry (0, 0, 0, 0); + + public LineNumberEntry (int file, int row, int column, int offset) + : this (file, row, column, offset, false) + { + } + + public LineNumberEntry (int file, int row, int offset) + : this (file, row, -1, offset, false) + { + } + + public LineNumberEntry (int file, int row, int column, int offset, bool is_hidden) + : this (file, row, column, -1, -1, offset, is_hidden) + { + } + + public LineNumberEntry (int file, int row, int column, int end_row, int end_column, int offset, bool is_hidden) + { + this.File = file; + this.Row = row; + this.Column = column; + this.EndRow = end_row; + this.EndColumn = end_column; + this.Offset = offset; + this.IsHidden = is_hidden; + } + + public override string ToString () + { + return String.Format ("[Line {0}:{1,2}-{3,4}:{5}]", File, Row, Column, EndRow, EndColumn, Offset); + } + } + + public class CodeBlockEntry + { + public int Index; + #region This is actually written to the symbol file + public int Parent; + public Type BlockType; + public int StartOffset; + public int EndOffset; + #endregion + + public enum Type { + Lexical = 1, + CompilerGenerated = 2, + IteratorBody = 3, + IteratorDispatcher = 4 + } + + public CodeBlockEntry (int index, int parent, Type type, int start_offset) + { + this.Index = index; + this.Parent = parent; + this.BlockType = type; + this.StartOffset = start_offset; + } + + internal CodeBlockEntry (int index, MyBinaryReader reader) + { + this.Index = index; + int type_flag = reader.ReadLeb128 (); + BlockType = (Type) (type_flag & 0x3f); + this.Parent = reader.ReadLeb128 (); + this.StartOffset = reader.ReadLeb128 (); + this.EndOffset = reader.ReadLeb128 (); + + /* Reserved for future extensions. */ + if ((type_flag & 0x40) != 0) { + int data_size = reader.ReadInt16 (); + reader.BaseStream.Position += data_size; + } + } + + public void Close (int end_offset) + { + this.EndOffset = end_offset; + } + + internal void Write (MyBinaryWriter bw) + { + bw.WriteLeb128 ((int) BlockType); + bw.WriteLeb128 (Parent); + bw.WriteLeb128 (StartOffset); + bw.WriteLeb128 (EndOffset); + } + + public override string ToString () + { + return String.Format ("[CodeBlock {0}:{1}:{2}:{3}:{4}]", + Index, Parent, BlockType, StartOffset, EndOffset); + } + } + + public struct LocalVariableEntry + { + #region This is actually written to the symbol file + public readonly int Index; + public readonly string Name; + public readonly int BlockIndex; + #endregion + + public LocalVariableEntry (int index, string name, int block) + { + this.Index = index; + this.Name = name; + this.BlockIndex = block; + } + + internal LocalVariableEntry (MonoSymbolFile file, MyBinaryReader reader) + { + Index = reader.ReadLeb128 (); + Name = reader.ReadString (); + BlockIndex = reader.ReadLeb128 (); + } + + internal void Write (MonoSymbolFile file, MyBinaryWriter bw) + { + bw.WriteLeb128 (Index); + bw.Write (Name); + bw.WriteLeb128 (BlockIndex); + } + + public override string ToString () + { + return String.Format ("[LocalVariable {0}:{1}:{2}]", + Name, Index, BlockIndex - 1); + } + } + + public struct CapturedVariable + { + #region This is actually written to the symbol file + public readonly string Name; + public readonly string CapturedName; + public readonly CapturedKind Kind; + #endregion + + public enum CapturedKind : byte + { + Local, + Parameter, + This + } + + public CapturedVariable (string name, string captured_name, + CapturedKind kind) + { + this.Name = name; + this.CapturedName = captured_name; + this.Kind = kind; + } + + internal CapturedVariable (MyBinaryReader reader) + { + Name = reader.ReadString (); + CapturedName = reader.ReadString (); + Kind = (CapturedKind) reader.ReadByte (); + } + + internal void Write (MyBinaryWriter bw) + { + bw.Write (Name); + bw.Write (CapturedName); + bw.Write ((byte) Kind); + } + + public override string ToString () + { + return String.Format ("[CapturedVariable {0}:{1}:{2}]", + Name, CapturedName, Kind); + } + } + + public struct CapturedScope + { + #region This is actually written to the symbol file + public readonly int Scope; + public readonly string CapturedName; + #endregion + + public CapturedScope (int scope, string captured_name) + { + this.Scope = scope; + this.CapturedName = captured_name; + } + + internal CapturedScope (MyBinaryReader reader) + { + Scope = reader.ReadLeb128 (); + CapturedName = reader.ReadString (); + } + + internal void Write (MyBinaryWriter bw) + { + bw.WriteLeb128 (Scope); + bw.Write (CapturedName); + } + + public override string ToString () + { + return String.Format ("[CapturedScope {0}:{1}]", + Scope, CapturedName); + } + } + + public struct ScopeVariable + { + #region This is actually written to the symbol file + public readonly int Scope; + public readonly int Index; + #endregion + + public ScopeVariable (int scope, int index) + { + this.Scope = scope; + this.Index = index; + } + + internal ScopeVariable (MyBinaryReader reader) + { + Scope = reader.ReadLeb128 (); + Index = reader.ReadLeb128 (); + } + + internal void Write (MyBinaryWriter bw) + { + bw.WriteLeb128 (Scope); + bw.WriteLeb128 (Index); + } + + public override string ToString () + { + return String.Format ("[ScopeVariable {0}:{1}]", Scope, Index); + } + } + + public class AnonymousScopeEntry + { + #region This is actually written to the symbol file + public readonly int ID; + #endregion + + List captured_vars = new List (); + List captured_scopes = new List (); + + public AnonymousScopeEntry (int id) + { + this.ID = id; + } + + internal AnonymousScopeEntry (MyBinaryReader reader) + { + ID = reader.ReadLeb128 (); + + int num_captured_vars = reader.ReadLeb128 (); + for (int i = 0; i < num_captured_vars; i++) + captured_vars.Add (new CapturedVariable (reader)); + + int num_captured_scopes = reader.ReadLeb128 (); + for (int i = 0; i < num_captured_scopes; i++) + captured_scopes.Add (new CapturedScope (reader)); + } + + internal void AddCapturedVariable (string name, string captured_name, + CapturedVariable.CapturedKind kind) + { + captured_vars.Add (new CapturedVariable (name, captured_name, kind)); + } + + public CapturedVariable[] CapturedVariables { + get { + CapturedVariable[] retval = new CapturedVariable [captured_vars.Count]; + captured_vars.CopyTo (retval, 0); + return retval; + } + } + + internal void AddCapturedScope (int scope, string captured_name) + { + captured_scopes.Add (new CapturedScope (scope, captured_name)); + } + + public CapturedScope[] CapturedScopes { + get { + CapturedScope[] retval = new CapturedScope [captured_scopes.Count]; + captured_scopes.CopyTo (retval, 0); + return retval; + } + } + + internal void Write (MyBinaryWriter bw) + { + bw.WriteLeb128 (ID); + + bw.WriteLeb128 (captured_vars.Count); + foreach (CapturedVariable cv in captured_vars) + cv.Write (bw); + + bw.WriteLeb128 (captured_scopes.Count); + foreach (CapturedScope cs in captured_scopes) + cs.Write (bw); + } + + public override string ToString () + { + return String.Format ("[AnonymousScope {0}]", ID); + } + } + + public class CompileUnitEntry : ICompileUnit + { + #region This is actually written to the symbol file + public readonly int Index; + int DataOffset; + #endregion + + MonoSymbolFile file; + SourceFileEntry source; + List include_files; + List namespaces; + + bool creating; + + public static int Size { + get { return 8; } + } + + CompileUnitEntry ICompileUnit.Entry { + get { return this; } + } + + public CompileUnitEntry (MonoSymbolFile file, SourceFileEntry source) + { + this.file = file; + this.source = source; + + this.Index = file.AddCompileUnit (this); + + creating = true; + namespaces = new List (); + } + + public void AddFile (SourceFileEntry file) + { + if (!creating) + throw new InvalidOperationException (); + + if (include_files == null) + include_files = new List (); + + include_files.Add (file); + } + + public SourceFileEntry SourceFile { + get { + if (creating) + return source; + + ReadData (); + return source; + } + } + + public int DefineNamespace (string name, string[] using_clauses, int parent) + { + if (!creating) + throw new InvalidOperationException (); + + int index = file.GetNextNamespaceIndex (); + NamespaceEntry ns = new NamespaceEntry (name, index, using_clauses, parent); + namespaces.Add (ns); + return index; + } + + internal void WriteData (MyBinaryWriter bw) + { + DataOffset = (int) bw.BaseStream.Position; + bw.WriteLeb128 (source.Index); + + int count_includes = include_files != null ? include_files.Count : 0; + bw.WriteLeb128 (count_includes); + if (include_files != null) { + foreach (SourceFileEntry entry in include_files) + bw.WriteLeb128 (entry.Index); + } + + bw.WriteLeb128 (namespaces.Count); + foreach (NamespaceEntry ns in namespaces) + ns.Write (file, bw); + } + + internal void Write (BinaryWriter bw) + { + bw.Write (Index); + bw.Write (DataOffset); + } + + internal CompileUnitEntry (MonoSymbolFile file, MyBinaryReader reader) + { + this.file = file; + + Index = reader.ReadInt32 (); + DataOffset = reader.ReadInt32 (); + } + + public void ReadAll () + { + ReadData (); + } + + void ReadData () + { + if (creating) + throw new InvalidOperationException (); + + lock (file) { + if (namespaces != null) + return; + + MyBinaryReader reader = file.BinaryReader; + int old_pos = (int) reader.BaseStream.Position; + + reader.BaseStream.Position = DataOffset; + + int source_idx = reader.ReadLeb128 (); + source = file.GetSourceFile (source_idx); + + int count_includes = reader.ReadLeb128 (); + if (count_includes > 0) { + include_files = new List (); + for (int i = 0; i < count_includes; i++) + include_files.Add (file.GetSourceFile (reader.ReadLeb128 ())); + } + + int count_ns = reader.ReadLeb128 (); + namespaces = new List (); + for (int i = 0; i < count_ns; i ++) + namespaces.Add (new NamespaceEntry (file, reader)); + + reader.BaseStream.Position = old_pos; + } + } + + public NamespaceEntry[] Namespaces { + get { + ReadData (); + NamespaceEntry[] retval = new NamespaceEntry [namespaces.Count]; + namespaces.CopyTo (retval, 0); + return retval; + } + } + + public SourceFileEntry[] IncludeFiles { + get { + ReadData (); + if (include_files == null) + return new SourceFileEntry [0]; + + SourceFileEntry[] retval = new SourceFileEntry [include_files.Count]; + include_files.CopyTo (retval, 0); + return retval; + } + } + } + + public class SourceFileEntry + { + #region This is actually written to the symbol file + public readonly int Index; + int DataOffset; + #endregion + + MonoSymbolFile file; + string file_name; + byte[] guid; + byte[] hash; + bool creating; + bool auto_generated; + readonly string sourceFile; + + public static int Size { + get { return 8; } + } + + public SourceFileEntry (MonoSymbolFile file, string file_name) + { + this.file = file; + this.file_name = file_name; + this.Index = file.AddSource (this); + + creating = true; + } + + public SourceFileEntry (MonoSymbolFile file, string sourceFile, byte [] guid, byte [] checksum) + : this (file, sourceFile, sourceFile, guid, checksum) + { + } + + public SourceFileEntry (MonoSymbolFile file, string fileName, string sourceFile, byte[] guid, byte[] checksum) + : this (file, fileName) + { + this.guid = guid; + this.hash = checksum; + this.sourceFile = sourceFile; + } + + public byte[] Checksum { + get { + return hash; + } + } + + internal void WriteData (MyBinaryWriter bw) + { + DataOffset = (int) bw.BaseStream.Position; + bw.Write (file_name); + + if (guid == null) + guid = new byte[16]; + + if (hash == null) { + try { + using (FileStream fs = new FileStream (sourceFile, FileMode.Open, FileAccess.Read)) { + MD5 md5 = MD5.Create (); + hash = md5.ComputeHash (fs); + } + } catch { + hash = new byte [16]; + } + } + + bw.Write (guid); + bw.Write (hash); + bw.Write ((byte) (auto_generated ? 1 : 0)); + } + + internal void Write (BinaryWriter bw) + { + bw.Write (Index); + bw.Write (DataOffset); + } + + internal SourceFileEntry (MonoSymbolFile file, MyBinaryReader reader) + { + this.file = file; + + Index = reader.ReadInt32 (); + DataOffset = reader.ReadInt32 (); + + int old_pos = (int) reader.BaseStream.Position; + reader.BaseStream.Position = DataOffset; + + sourceFile = file_name = reader.ReadString (); + guid = reader.ReadBytes (16); + hash = reader.ReadBytes (16); + auto_generated = reader.ReadByte () == 1; + + reader.BaseStream.Position = old_pos; + } + + public string FileName { + get { return file_name; } + set { file_name = value; } + } + + public bool AutoGenerated { + get { return auto_generated; } + } + + public void SetAutoGenerated () + { + if (!creating) + throw new InvalidOperationException (); + + auto_generated = true; + file.OffsetTable.FileFlags |= OffsetTable.Flags.IsAspxSource; + } + + public bool CheckChecksum () + { + try { + using (FileStream fs = new FileStream (sourceFile, FileMode.Open)) { + MD5 md5 = MD5.Create (); + byte[] data = md5.ComputeHash (fs); + for (int i = 0; i < 16; i++) + if (data [i] != hash [i]) + return false; + return true; + } + } catch { + return false; + } + } + + public override string ToString () + { + return String.Format ("SourceFileEntry ({0}:{1})", Index, DataOffset); + } + } + + public class LineNumberTable + { + protected LineNumberEntry[] _line_numbers; + public LineNumberEntry[] LineNumbers { + get { return _line_numbers; } + } + + public readonly int LineBase; + public readonly int LineRange; + public readonly byte OpcodeBase; + public readonly int MaxAddressIncrement; + +#region Configurable constants + public const int Default_LineBase = -1; + public const int Default_LineRange = 8; + public const byte Default_OpcodeBase = 9; + +#endregion + + public const byte DW_LNS_copy = 1; + public const byte DW_LNS_advance_pc = 2; + public const byte DW_LNS_advance_line = 3; + public const byte DW_LNS_set_file = 4; + public const byte DW_LNS_const_add_pc = 8; + + public const byte DW_LNE_end_sequence = 1; + + // MONO extensions. + public const byte DW_LNE_MONO_negate_is_hidden = 0x40; + + internal const byte DW_LNE_MONO__extensions_start = 0x40; + internal const byte DW_LNE_MONO__extensions_end = 0x7f; + + protected LineNumberTable (MonoSymbolFile file) + { + this.LineBase = file.OffsetTable.LineNumberTable_LineBase; + this.LineRange = file.OffsetTable.LineNumberTable_LineRange; + this.OpcodeBase = (byte) file.OffsetTable.LineNumberTable_OpcodeBase; + this.MaxAddressIncrement = (255 - OpcodeBase) / LineRange; + } + + internal LineNumberTable (MonoSymbolFile file, LineNumberEntry[] lines) + : this (file) + { + this._line_numbers = lines; + } + + internal void Write (MonoSymbolFile file, MyBinaryWriter bw, bool hasColumnsInfo, bool hasEndInfo) + { + int start = (int) bw.BaseStream.Position; + + bool last_is_hidden = false; + int last_line = 1, last_offset = 0, last_file = 1; + for (int i = 0; i < LineNumbers.Length; i++) { + int line_inc = LineNumbers [i].Row - last_line; + int offset_inc = LineNumbers [i].Offset - last_offset; + + if (LineNumbers [i].File != last_file) { + bw.Write (DW_LNS_set_file); + bw.WriteLeb128 (LineNumbers [i].File); + last_file = LineNumbers [i].File; + } + + if (LineNumbers [i].IsHidden != last_is_hidden) { + bw.Write ((byte) 0); + bw.Write ((byte) 1); + bw.Write (DW_LNE_MONO_negate_is_hidden); + last_is_hidden = LineNumbers [i].IsHidden; + } + + if (offset_inc >= MaxAddressIncrement) { + if (offset_inc < 2 * MaxAddressIncrement) { + bw.Write (DW_LNS_const_add_pc); + offset_inc -= MaxAddressIncrement; + } else { + bw.Write (DW_LNS_advance_pc); + bw.WriteLeb128 (offset_inc); + offset_inc = 0; + } + } + + if ((line_inc < LineBase) || (line_inc >= LineBase + LineRange)) { + bw.Write (DW_LNS_advance_line); + bw.WriteLeb128 (line_inc); + if (offset_inc != 0) { + bw.Write (DW_LNS_advance_pc); + bw.WriteLeb128 (offset_inc); + } + bw.Write (DW_LNS_copy); + } else { + byte opcode; + opcode = (byte) (line_inc - LineBase + (LineRange * offset_inc) + + OpcodeBase); + bw.Write (opcode); + } + + last_line = LineNumbers [i].Row; + last_offset = LineNumbers [i].Offset; + } + + bw.Write ((byte) 0); + bw.Write ((byte) 1); + bw.Write (DW_LNE_end_sequence); + + if (hasColumnsInfo) { + for (int i = 0; i < LineNumbers.Length; i++) { + var ln = LineNumbers [i]; + if (ln.Row >= 0) + bw.WriteLeb128 (ln.Column); + } + } + + if (hasEndInfo) { + for (int i = 0; i < LineNumbers.Length; i++) { + var ln = LineNumbers [i]; + if (ln.EndRow == -1 || ln.EndColumn == -1 || ln.Row > ln.EndRow) { + bw.WriteLeb128 (0xffffff); + } else { + bw.WriteLeb128 (ln.EndRow - ln.Row); + bw.WriteLeb128 (ln.EndColumn); + } + } + } + + file.ExtendedLineNumberSize += (int) bw.BaseStream.Position - start; + } + + internal static LineNumberTable Read (MonoSymbolFile file, MyBinaryReader br, bool readColumnsInfo, bool readEndInfo) + { + LineNumberTable lnt = new LineNumberTable (file); + lnt.DoRead (file, br, readColumnsInfo, readEndInfo); + return lnt; + } + + void DoRead (MonoSymbolFile file, MyBinaryReader br, bool includesColumns, bool includesEnds) + { + var lines = new List (); + + bool is_hidden = false, modified = false; + int stm_line = 1, stm_offset = 0, stm_file = 1; + while (true) { + byte opcode = br.ReadByte (); + + if (opcode == 0) { + byte size = br.ReadByte (); + long end_pos = br.BaseStream.Position + size; + opcode = br.ReadByte (); + + if (opcode == DW_LNE_end_sequence) { + if (modified) + lines.Add (new LineNumberEntry ( + stm_file, stm_line, -1, stm_offset, is_hidden)); + break; + } else if (opcode == DW_LNE_MONO_negate_is_hidden) { + is_hidden = !is_hidden; + modified = true; + } else if ((opcode >= DW_LNE_MONO__extensions_start) && + (opcode <= DW_LNE_MONO__extensions_end)) { + ; // reserved for future extensions + } else { + throw new MonoSymbolFileException ("Unknown extended opcode {0:x}", opcode); + } + + br.BaseStream.Position = end_pos; + continue; + } else if (opcode < OpcodeBase) { + switch (opcode) { + case DW_LNS_copy: + lines.Add (new LineNumberEntry ( + stm_file, stm_line, -1, stm_offset, is_hidden)); + modified = false; + break; + case DW_LNS_advance_pc: + stm_offset += br.ReadLeb128 (); + modified = true; + break; + case DW_LNS_advance_line: + stm_line += br.ReadLeb128 (); + modified = true; + break; + case DW_LNS_set_file: + stm_file = br.ReadLeb128 (); + modified = true; + break; + case DW_LNS_const_add_pc: + stm_offset += MaxAddressIncrement; + modified = true; + break; + default: + throw new MonoSymbolFileException ( + "Unknown standard opcode {0:x} in LNT", + opcode); + } + } else { + opcode -= OpcodeBase; + + stm_offset += opcode / LineRange; + stm_line += LineBase + (opcode % LineRange); + lines.Add (new LineNumberEntry ( + stm_file, stm_line, -1, stm_offset, is_hidden)); + modified = false; + } + } + + _line_numbers = lines.ToArray (); + + if (includesColumns) { + for (int i = 0; i < _line_numbers.Length; ++i) { + var ln = _line_numbers[i]; + if (ln.Row >= 0) + ln.Column = br.ReadLeb128 (); + } + } + if (includesEnds) { + for (int i = 0; i < _line_numbers.Length; ++i) { + var ln = _line_numbers[i]; + + int row = br.ReadLeb128 (); + if (row == 0xffffff) { + ln.EndRow = -1; + ln.EndColumn = -1; + } else { + ln.EndRow = ln.Row + row; + ln.EndColumn = br.ReadLeb128 (); + } + } + } + } + + public bool GetMethodBounds (out LineNumberEntry start, out LineNumberEntry end) + { + if (_line_numbers.Length > 1) { + start = _line_numbers [0]; + end = _line_numbers [_line_numbers.Length - 1]; + return true; + } + + start = LineNumberEntry.Null; + end = LineNumberEntry.Null; + return false; + } + } + + public class MethodEntry : IComparable + { + #region This is actually written to the symbol file + public readonly int CompileUnitIndex; + public readonly int Token; + public readonly int NamespaceID; + + int DataOffset; + int LocalVariableTableOffset; + int LineNumberTableOffset; + int CodeBlockTableOffset; + int ScopeVariableTableOffset; + int RealNameOffset; + Flags flags; + #endregion + + int index; + + public Flags MethodFlags { + get { return flags; } + } + + public readonly CompileUnitEntry CompileUnit; + + LocalVariableEntry[] locals; + CodeBlockEntry[] code_blocks; + ScopeVariable[] scope_vars; + LineNumberTable lnt; + string real_name; + + public readonly MonoSymbolFile SymbolFile; + + public int Index { + get { return index; } + set { index = value; } + } + + [Flags] + public enum Flags + { + LocalNamesAmbiguous = 1, + ColumnsInfoIncluded = 1 << 1, + EndInfoIncluded = 1 << 2 + } + + public const int Size = 12; + + internal MethodEntry (MonoSymbolFile file, MyBinaryReader reader, int index) + { + this.SymbolFile = file; + this.index = index; + + Token = reader.ReadInt32 (); + DataOffset = reader.ReadInt32 (); + LineNumberTableOffset = reader.ReadInt32 (); + + long old_pos = reader.BaseStream.Position; + reader.BaseStream.Position = DataOffset; + + CompileUnitIndex = reader.ReadLeb128 (); + LocalVariableTableOffset = reader.ReadLeb128 (); + NamespaceID = reader.ReadLeb128 (); + + CodeBlockTableOffset = reader.ReadLeb128 (); + ScopeVariableTableOffset = reader.ReadLeb128 (); + + RealNameOffset = reader.ReadLeb128 (); + + flags = (Flags) reader.ReadLeb128 (); + + reader.BaseStream.Position = old_pos; + + CompileUnit = file.GetCompileUnit (CompileUnitIndex); + } + + internal MethodEntry (MonoSymbolFile file, CompileUnitEntry comp_unit, + int token, ScopeVariable[] scope_vars, + LocalVariableEntry[] locals, LineNumberEntry[] lines, + CodeBlockEntry[] code_blocks, string real_name, + Flags flags, int namespace_id) + { + this.SymbolFile = file; + this.real_name = real_name; + this.locals = locals; + this.code_blocks = code_blocks; + this.scope_vars = scope_vars; + this.flags = flags; + + index = -1; + + Token = token; + CompileUnitIndex = comp_unit.Index; + CompileUnit = comp_unit; + NamespaceID = namespace_id; + + CheckLineNumberTable (lines); + lnt = new LineNumberTable (file, lines); + file.NumLineNumbers += lines.Length; + + int num_locals = locals != null ? locals.Length : 0; + + if (num_locals <= 32) { + // Most of the time, the O(n^2) factor is actually + // less than the cost of allocating the hash table, + // 32 is a rough number obtained through some testing. + + for (int i = 0; i < num_locals; i ++) { + string nm = locals [i].Name; + + for (int j = i + 1; j < num_locals; j ++) { + if (locals [j].Name == nm) { + flags |= Flags.LocalNamesAmbiguous; + goto locals_check_done; + } + } + } + locals_check_done : + ; + } else { + var local_names = new Dictionary (); + foreach (LocalVariableEntry local in locals) { + if (local_names.ContainsKey (local.Name)) { + flags |= Flags.LocalNamesAmbiguous; + break; + } + local_names.Add (local.Name, local); + } + } + } + + static void CheckLineNumberTable (LineNumberEntry[] line_numbers) + { + int last_offset = -1; + int last_row = -1; + + if (line_numbers == null) + return; + + for (int i = 0; i < line_numbers.Length; i++) { + LineNumberEntry line = line_numbers [i]; + + if (line.Equals (LineNumberEntry.Null)) + throw new MonoSymbolFileException (); + + if (line.Offset < last_offset) + throw new MonoSymbolFileException (); + + if (line.Offset > last_offset) { + last_row = line.Row; + last_offset = line.Offset; + } else if (line.Row > last_row) { + last_row = line.Row; + } + } + } + + internal void Write (MyBinaryWriter bw) + { + if ((index <= 0) || (DataOffset == 0)) + throw new InvalidOperationException (); + + bw.Write (Token); + bw.Write (DataOffset); + bw.Write (LineNumberTableOffset); + } + + internal void WriteData (MonoSymbolFile file, MyBinaryWriter bw) + { + if (index <= 0) + throw new InvalidOperationException (); + + LocalVariableTableOffset = (int) bw.BaseStream.Position; + int num_locals = locals != null ? locals.Length : 0; + bw.WriteLeb128 (num_locals); + for (int i = 0; i < num_locals; i++) + locals [i].Write (file, bw); + file.LocalCount += num_locals; + + CodeBlockTableOffset = (int) bw.BaseStream.Position; + int num_code_blocks = code_blocks != null ? code_blocks.Length : 0; + bw.WriteLeb128 (num_code_blocks); + for (int i = 0; i < num_code_blocks; i++) + code_blocks [i].Write (bw); + + ScopeVariableTableOffset = (int) bw.BaseStream.Position; + int num_scope_vars = scope_vars != null ? scope_vars.Length : 0; + bw.WriteLeb128 (num_scope_vars); + for (int i = 0; i < num_scope_vars; i++) + scope_vars [i].Write (bw); + + if (real_name != null) { + RealNameOffset = (int) bw.BaseStream.Position; + bw.Write (real_name); + } + + foreach (var lne in lnt.LineNumbers) { + if (lne.EndRow != -1 || lne.EndColumn != -1) + flags |= Flags.EndInfoIncluded; + } + + LineNumberTableOffset = (int) bw.BaseStream.Position; + lnt.Write (file, bw, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); + + DataOffset = (int) bw.BaseStream.Position; + + bw.WriteLeb128 (CompileUnitIndex); + bw.WriteLeb128 (LocalVariableTableOffset); + bw.WriteLeb128 (NamespaceID); + + bw.WriteLeb128 (CodeBlockTableOffset); + bw.WriteLeb128 (ScopeVariableTableOffset); + + bw.WriteLeb128 (RealNameOffset); + bw.WriteLeb128 ((int) flags); + } + + public void ReadAll () + { + GetLineNumberTable (); + GetLocals (); + GetCodeBlocks (); + GetScopeVariables (); + GetRealName (); + } + + public LineNumberTable GetLineNumberTable () + { + lock (SymbolFile) { + if (lnt != null) + return lnt; + + if (LineNumberTableOffset == 0) + return null; + + MyBinaryReader reader = SymbolFile.BinaryReader; + long old_pos = reader.BaseStream.Position; + reader.BaseStream.Position = LineNumberTableOffset; + + lnt = LineNumberTable.Read (SymbolFile, reader, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); + + reader.BaseStream.Position = old_pos; + return lnt; + } + } + + public LocalVariableEntry[] GetLocals () + { + lock (SymbolFile) { + if (locals != null) + return locals; + + if (LocalVariableTableOffset == 0) + return null; + + MyBinaryReader reader = SymbolFile.BinaryReader; + long old_pos = reader.BaseStream.Position; + reader.BaseStream.Position = LocalVariableTableOffset; + + int num_locals = reader.ReadLeb128 (); + locals = new LocalVariableEntry [num_locals]; + + for (int i = 0; i < num_locals; i++) + locals [i] = new LocalVariableEntry (SymbolFile, reader); + + reader.BaseStream.Position = old_pos; + return locals; + } + } + + public CodeBlockEntry[] GetCodeBlocks () + { + lock (SymbolFile) { + if (code_blocks != null) + return code_blocks; + + if (CodeBlockTableOffset == 0) + return null; + + MyBinaryReader reader = SymbolFile.BinaryReader; + long old_pos = reader.BaseStream.Position; + reader.BaseStream.Position = CodeBlockTableOffset; + + int num_code_blocks = reader.ReadLeb128 (); + code_blocks = new CodeBlockEntry [num_code_blocks]; + + for (int i = 0; i < num_code_blocks; i++) + code_blocks [i] = new CodeBlockEntry (i, reader); + + reader.BaseStream.Position = old_pos; + return code_blocks; + } + } + + public ScopeVariable[] GetScopeVariables () + { + lock (SymbolFile) { + if (scope_vars != null) + return scope_vars; + + if (ScopeVariableTableOffset == 0) + return null; + + MyBinaryReader reader = SymbolFile.BinaryReader; + long old_pos = reader.BaseStream.Position; + reader.BaseStream.Position = ScopeVariableTableOffset; + + int num_scope_vars = reader.ReadLeb128 (); + scope_vars = new ScopeVariable [num_scope_vars]; + + for (int i = 0; i < num_scope_vars; i++) + scope_vars [i] = new ScopeVariable (reader); + + reader.BaseStream.Position = old_pos; + return scope_vars; + } + } + + public string GetRealName () + { + lock (SymbolFile) { + if (real_name != null) + return real_name; + + if (RealNameOffset == 0) + return null; + + real_name = SymbolFile.BinaryReader.ReadString (RealNameOffset); + return real_name; + } + } + + public int CompareTo (object obj) + { + MethodEntry method = (MethodEntry) obj; + + if (method.Token < Token) + return 1; + else if (method.Token > Token) + return -1; + else + return 0; + } + + public override string ToString () + { + return String.Format ("[Method {0}:{1:x}:{2}:{3}]", + index, Token, CompileUnitIndex, CompileUnit); + } + } + + public struct NamespaceEntry + { + #region This is actually written to the symbol file + public readonly string Name; + public readonly int Index; + public readonly int Parent; + public readonly string[] UsingClauses; + #endregion + + public NamespaceEntry (string name, int index, string[] using_clauses, int parent) + { + this.Name = name; + this.Index = index; + this.Parent = parent; + this.UsingClauses = using_clauses != null ? using_clauses : new string [0]; + } + + internal NamespaceEntry (MonoSymbolFile file, MyBinaryReader reader) + { + Name = reader.ReadString (); + Index = reader.ReadLeb128 (); + Parent = reader.ReadLeb128 (); + + int count = reader.ReadLeb128 (); + UsingClauses = new string [count]; + for (int i = 0; i < count; i++) + UsingClauses [i] = reader.ReadString (); + } + + internal void Write (MonoSymbolFile file, MyBinaryWriter bw) + { + bw.Write (Name); + bw.WriteLeb128 (Index); + bw.WriteLeb128 (Parent); + bw.WriteLeb128 (UsingClauses.Length); + foreach (string uc in UsingClauses) + bw.Write (uc); + } + + public override string ToString () + { + return String.Format ("[Namespace {0}:{1}:{2}]", Name, Index, Parent); + } + } +} diff --git a/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs b/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs new file mode 100644 index 00000000..19e14c2f --- /dev/null +++ b/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs @@ -0,0 +1,238 @@ +// +// Mono.CSharp.Debugger/MonoSymbolWriter.cs +// +// Author: +// Martin Baulig (martin@ximian.com) +// +// This is the default implementation of the System.Diagnostics.SymbolStore.ISymbolWriter +// interface. +// +// (C) 2002 Ximian, Inc. http://www.ximian.com +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Runtime.CompilerServices; +using System.Collections.Generic; +using System.IO; + +namespace Mono.CompilerServices.SymbolWriter +{ + public class MonoSymbolWriter + { + List methods; + List sources; + List comp_units; + protected readonly MonoSymbolFile file; + string filename; + + private SourceMethodBuilder current_method; + Stack current_method_stack = new Stack (); + + public MonoSymbolWriter (string filename) + { + this.methods = new List (); + this.sources = new List (); + this.comp_units = new List (); + this.file = new MonoSymbolFile (); + + this.filename = filename + ".mdb"; + } + + public MonoSymbolFile SymbolFile { + get { return file; } + } + + public void CloseNamespace () + { } + + public void DefineLocalVariable (int index, string name) + { + if (current_method == null) + return; + + current_method.AddLocal (index, name); + } + + public void DefineCapturedLocal (int scope_id, string name, string captured_name) + { + file.DefineCapturedVariable (scope_id, name, captured_name, + CapturedVariable.CapturedKind.Local); + } + + public void DefineCapturedParameter (int scope_id, string name, string captured_name) + { + file.DefineCapturedVariable (scope_id, name, captured_name, + CapturedVariable.CapturedKind.Parameter); + } + + public void DefineCapturedThis (int scope_id, string captured_name) + { + file.DefineCapturedVariable (scope_id, "this", captured_name, + CapturedVariable.CapturedKind.This); + } + + public void DefineCapturedScope (int scope_id, int id, string captured_name) + { + file.DefineCapturedScope (scope_id, id, captured_name); + } + + public void DefineScopeVariable (int scope, int index) + { + if (current_method == null) + return; + + current_method.AddScopeVariable (scope, index); + } + + public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, + bool is_hidden) + { + if (current_method == null) + return; + + current_method.MarkSequencePoint (offset, file, line, column, is_hidden); + } + + public SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id, IMethodDef method) + { + SourceMethodBuilder builder = new SourceMethodBuilder (file, ns_id, method); + current_method_stack.Push (current_method); + current_method = builder; + methods.Add (current_method); + return builder; + } + + public void CloseMethod () + { + current_method = (SourceMethodBuilder) current_method_stack.Pop (); + } + + public SourceFileEntry DefineDocument (string url) + { + SourceFileEntry entry = new SourceFileEntry (file, url); + sources.Add (entry); + return entry; + } + + public SourceFileEntry DefineDocument (string url, byte[] guid, byte[] checksum) + { + SourceFileEntry entry = new SourceFileEntry (file, url, guid, checksum); + sources.Add (entry); + return entry; + } + + public CompileUnitEntry DefineCompilationUnit (SourceFileEntry source) + { + CompileUnitEntry entry = new CompileUnitEntry (file, source); + comp_units.Add (entry); + return entry; + } + + public int DefineNamespace (string name, CompileUnitEntry unit, + string[] using_clauses, int parent) + { + if ((unit == null) || (using_clauses == null)) + throw new NullReferenceException (); + + return unit.DefineNamespace (name, using_clauses, parent); + } + + public int OpenScope (int start_offset) + { + if (current_method == null) + return 0; + + current_method.StartBlock (CodeBlockEntry.Type.Lexical, start_offset); + return 0; + } + + public void CloseScope (int end_offset) + { + if (current_method == null) + return; + + current_method.EndBlock (end_offset); + } + + public void OpenCompilerGeneratedBlock (int start_offset) + { + if (current_method == null) + return; + + current_method.StartBlock (CodeBlockEntry.Type.CompilerGenerated, + start_offset); + } + + public void CloseCompilerGeneratedBlock (int end_offset) + { + if (current_method == null) + return; + + current_method.EndBlock (end_offset); + } + + public void StartIteratorBody (int start_offset) + { + current_method.StartBlock (CodeBlockEntry.Type.IteratorBody, + start_offset); + } + + public void EndIteratorBody (int end_offset) + { + current_method.EndBlock (end_offset); + } + + public void StartIteratorDispatcher (int start_offset) + { + current_method.StartBlock (CodeBlockEntry.Type.IteratorDispatcher, + start_offset); + } + + public void EndIteratorDispatcher (int end_offset) + { + current_method.EndBlock (end_offset); + } + + public void DefineAnonymousScope (int id) + { + file.DefineAnonymousScope (id); + } + + public void WriteSymbolFile (Guid guid) + { + foreach (SourceMethodBuilder method in methods) + method.DefineMethod (file); + + try { + // We mmap the file, so unlink the previous version since it may be in use + File.Delete (filename); + } catch { + // We can safely ignore + } + using (FileStream fs = new FileStream (filename, FileMode.Create, FileAccess.Write)) { + file.CreateSymbolFile (guid, fs); + } + } + } +} diff --git a/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs b/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs new file mode 100644 index 00000000..094425cf --- /dev/null +++ b/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs @@ -0,0 +1,246 @@ +// +// SourceMethodBuilder.cs +// +// Authors: +// Martin Baulig (martin@ximian.com) +// Marek Safar (marek.safar@gmail.com) +// +// (C) 2002 Ximian, Inc. http://www.ximian.com +// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; + +namespace Mono.CompilerServices.SymbolWriter +{ + public class SourceMethodBuilder + { + List _locals; + List _blocks; + List _scope_vars; + Stack _block_stack; + readonly List method_lines; + + readonly ICompileUnit _comp_unit; + readonly int ns_id; + readonly IMethodDef method; + + public SourceMethodBuilder (ICompileUnit comp_unit) + { + this._comp_unit = comp_unit; + method_lines = new List (); + } + + public SourceMethodBuilder (ICompileUnit comp_unit, int ns_id, IMethodDef method) + : this (comp_unit) + { + this.ns_id = ns_id; + this.method = method; + } + + public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, bool is_hidden) + { + MarkSequencePoint (offset, file, line, column, -1, -1, is_hidden); + } + + public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, int end_line, int end_column, bool is_hidden) + { + int file_idx = file != null ? file.Index : 0; + var lne = new LineNumberEntry (file_idx, line, column, end_line, end_column, offset, is_hidden); + + if (method_lines.Count > 0) { + var prev = method_lines[method_lines.Count - 1]; + + // + // Same offset cannot be used for multiple lines + // + if (prev.Offset == offset) { + // + // Use the new location because debugger will adjust + // the breakpoint to next line with sequence point + // + if (LineNumberEntry.LocationComparer.Default.Compare (lne, prev) > 0) + method_lines[method_lines.Count - 1] = lne; + + return; + } + } + + method_lines.Add (lne); + } + + public void StartBlock (CodeBlockEntry.Type type, int start_offset) + { + StartBlock (type, start_offset, _blocks == null ? 1 : _blocks.Count + 1); + } + + public void StartBlock (CodeBlockEntry.Type type, int start_offset, int scopeIndex) + { + if (_block_stack == null) { + _block_stack = new Stack (); + } + + if (_blocks == null) + _blocks = new List (); + + int parent = CurrentBlock != null ? CurrentBlock.Index : -1; + + CodeBlockEntry block = new CodeBlockEntry ( + scopeIndex, parent, type, start_offset); + + _block_stack.Push (block); + _blocks.Add (block); + } + + public void EndBlock (int end_offset) + { + CodeBlockEntry block = (CodeBlockEntry) _block_stack.Pop (); + block.Close (end_offset); + } + + public CodeBlockEntry[] Blocks { + get { + if (_blocks == null) + return new CodeBlockEntry [0]; + + CodeBlockEntry[] retval = new CodeBlockEntry [_blocks.Count]; + _blocks.CopyTo (retval, 0); + return retval; + } + } + + public CodeBlockEntry CurrentBlock { + get { + if ((_block_stack != null) && (_block_stack.Count > 0)) + return (CodeBlockEntry) _block_stack.Peek (); + else + return null; + } + } + + public LocalVariableEntry[] Locals { + get { + if (_locals == null) + return new LocalVariableEntry [0]; + else { + return _locals.ToArray (); + } + } + } + + public ICompileUnit SourceFile { + get { + return _comp_unit; + } + } + + public void AddLocal (int index, string name) + { + if (_locals == null) + _locals = new List (); + int block_idx = CurrentBlock != null ? CurrentBlock.Index : 0; + _locals.Add (new LocalVariableEntry (index, name, block_idx)); + } + + public ScopeVariable[] ScopeVariables { + get { + if (_scope_vars == null) + return new ScopeVariable [0]; + + return _scope_vars.ToArray (); + } + } + + public void AddScopeVariable (int scope, int index) + { + if (_scope_vars == null) + _scope_vars = new List (); + _scope_vars.Add ( + new ScopeVariable (scope, index)); + } + + public void DefineMethod (MonoSymbolFile file) + { + DefineMethod (file, method.Token); + } + + public void DefineMethod (MonoSymbolFile file, int token) + { + var blocks = Blocks; + if (blocks.Length > 0) { + // + // When index is provided by user it can be inserted in + // any order but mdb format does not store its value. It + // uses stored order as the index instead. + // + var sorted = new List (blocks.Length); + int max_index = 0; + for (int i = 0; i < blocks.Length; ++i) { + max_index = System.Math.Max (max_index, blocks [i].Index); + } + + for (int i = 0; i < max_index; ++i) { + var scope_index = i + 1; + + // + // Common fast path + // + if (i < blocks.Length && blocks [i].Index == scope_index) { + sorted.Add (blocks [i]); + continue; + } + + bool found = false; + for (int ii = 0; ii < blocks.Length; ++ii) { + if (blocks [ii].Index == scope_index) { + sorted.Add (blocks [ii]); + found = true; + break; + } + } + + if (found) + continue; + + // + // Ideally this should never happen but with current design we can + // generate scope index for unreachable code before reachable code + // + sorted.Add (new CodeBlockEntry (scope_index, -1, CodeBlockEntry.Type.CompilerGenerated, 0)); + } + + blocks = sorted.ToArray (); + //for (int i = 0; i < blocks.Length; ++i) { + // if (blocks [i].Index - 1 != i) + // throw new ArgumentException ("CodeBlocks cannot be converted to mdb format"); + //} + } + + var entry = new MethodEntry ( + file, _comp_unit.Entry, token, ScopeVariables, + Locals, method_lines.ToArray (), blocks, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id); + + file.AddMethod (entry); + } + } +} diff --git a/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs b/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs new file mode 100644 index 00000000..96e5fe19 --- /dev/null +++ b/Mono.Cecil.Mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs @@ -0,0 +1,352 @@ +// +// SymbolWriterImpl.cs +// +// Author: +// Lluis Sanchez Gual (lluis@novell.com) +// +// (C) 2005 Novell, Inc. http://www.novell.com +// +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +#if !NET_CORE + +using System; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; +using System.Collections; +using System.IO; +using System.Diagnostics.SymbolStore; + +namespace Mono.CompilerServices.SymbolWriter +{ + public class SymbolWriterImpl: ISymbolWriter + { + MonoSymbolWriter msw; + + int nextLocalIndex; + int currentToken; + string methodName; + Stack namespaceStack = new Stack (); + bool methodOpened; + + Hashtable documents = new Hashtable (); + +#if !CECIL + ModuleBuilder mb; + delegate Guid GetGuidFunc (ModuleBuilder mb); + GetGuidFunc get_guid_func; + + public SymbolWriterImpl (ModuleBuilder mb) + { + this.mb = mb; + } + + public void Close () + { + MethodInfo mi = typeof (ModuleBuilder).GetMethod ( + "Mono_GetGuid", + BindingFlags.Static | BindingFlags.NonPublic); + if (mi == null) + return; + + get_guid_func = (GetGuidFunc) System.Delegate.CreateDelegate ( + typeof (GetGuidFunc), mi); + + msw.WriteSymbolFile (get_guid_func (mb)); + } +#else + Guid guid; + + public SymbolWriterImpl (Guid guid) + { + this.guid = guid; + } + + public void Close () + { + msw.WriteSymbolFile (guid); + } +#endif + + public void CloseMethod () + { + if (methodOpened) { + methodOpened = false; + nextLocalIndex = 0; + msw.CloseMethod (); + } + } + + public void CloseNamespace () + { + namespaceStack.Pop (); + msw.CloseNamespace (); + } + + public void CloseScope (int endOffset) + { + msw.CloseScope (endOffset); + } + + public ISymbolDocumentWriter DefineDocument ( + string url, + Guid language, + Guid languageVendor, + Guid documentType) + { + SymbolDocumentWriterImpl doc = (SymbolDocumentWriterImpl) documents [url]; + if (doc == null) { + SourceFileEntry entry = msw.DefineDocument (url); + CompileUnitEntry comp_unit = msw.DefineCompilationUnit (entry); + doc = new SymbolDocumentWriterImpl (comp_unit); + documents [url] = doc; + } + return doc; + } + + public void DefineField ( + SymbolToken parent, + string name, + FieldAttributes attributes, + byte[] signature, + SymAddressKind addrKind, + int addr1, + int addr2, + int addr3) + { + } + + public void DefineGlobalVariable ( + string name, + FieldAttributes attributes, + byte[] signature, + SymAddressKind addrKind, + int addr1, + int addr2, + int addr3) + { + } + + public void DefineLocalVariable ( + string name, + FieldAttributes attributes, + byte[] signature, + SymAddressKind addrKind, + int addr1, + int addr2, + int addr3, + int startOffset, + int endOffset) + { + msw.DefineLocalVariable (nextLocalIndex++, name); + } + + public void DefineParameter ( + string name, + ParameterAttributes attributes, + int sequence, + SymAddressKind addrKind, + int addr1, + int addr2, + int addr3) + { + } + + public void DefineSequencePoints ( + ISymbolDocumentWriter document, + int[] offsets, + int[] lines, + int[] columns, + int[] endLines, + int[] endColumns) + { + SymbolDocumentWriterImpl doc = (SymbolDocumentWriterImpl) document; + SourceFileEntry file = doc != null ? doc.Entry.SourceFile : null; + + for (int n=0; n 0 && offsets[n] == offsets[n-1] && lines[n] == lines[n-1] && columns[n] == columns[n-1]) + continue; + msw.MarkSequencePoint (offsets[n], file, lines[n], columns[n], false); + } + } + + public void Initialize (IntPtr emitter, string filename, bool fFullBuild) + { + msw = new MonoSymbolWriter (filename); + } + + public void OpenMethod (SymbolToken method) + { + currentToken = method.GetToken (); + } + + public void OpenNamespace (string name) + { + NamespaceInfo n = new NamespaceInfo (); + n.NamespaceID = -1; + n.Name = name; + namespaceStack.Push (n); + } + + public int OpenScope (int startOffset) + { + return msw.OpenScope (startOffset); + } + + public void SetMethodSourceRange ( + ISymbolDocumentWriter startDoc, + int startLine, + int startColumn, + ISymbolDocumentWriter endDoc, + int endLine, + int endColumn) + { + int nsId = GetCurrentNamespace (startDoc); + SourceMethodImpl sm = new SourceMethodImpl (methodName, currentToken, nsId); + msw.OpenMethod (((ICompileUnit)startDoc).Entry, nsId, sm); + methodOpened = true; + } + + public void SetScopeRange (int scopeID, int startOffset, int endOffset) + { + } + + public void SetSymAttribute (SymbolToken parent, string name, byte[] data) + { + // This is a hack! but MonoSymbolWriter needs the method name + // and ISymbolWriter does not have any method for providing it + if (name == "__name") + methodName = System.Text.Encoding.UTF8.GetString (data); + } + + public void SetUnderlyingWriter (IntPtr underlyingWriter) + { + } + + public void SetUserEntryPoint (SymbolToken entryMethod) + { + } + + public void UsingNamespace (string fullName) + { + if (namespaceStack.Count == 0) { + OpenNamespace (""); + } + + NamespaceInfo ni = (NamespaceInfo) namespaceStack.Peek (); + if (ni.NamespaceID != -1) { + NamespaceInfo old = ni; + CloseNamespace (); + OpenNamespace (old.Name); + ni = (NamespaceInfo) namespaceStack.Peek (); + ni.UsingClauses = old.UsingClauses; + } + ni.UsingClauses.Add (fullName); + } + + int GetCurrentNamespace (ISymbolDocumentWriter doc) + { + if (namespaceStack.Count == 0) { + OpenNamespace (""); + } + + NamespaceInfo ni = (NamespaceInfo) namespaceStack.Peek (); + if (ni.NamespaceID == -1) + { + string[] usings = (string[]) ni.UsingClauses.ToArray (typeof(string)); + + int parentId = 0; + if (namespaceStack.Count > 1) { + namespaceStack.Pop (); + parentId = ((NamespaceInfo) namespaceStack.Peek ()).NamespaceID; + namespaceStack.Push (ni); + } + + ni.NamespaceID = msw.DefineNamespace (ni.Name, ((ICompileUnit)doc).Entry, usings, parentId); + } + return ni.NamespaceID; + } + + } + + class SymbolDocumentWriterImpl: ISymbolDocumentWriter, ISourceFile, ICompileUnit + { + CompileUnitEntry comp_unit; + + public SymbolDocumentWriterImpl (CompileUnitEntry comp_unit) + { + this.comp_unit = comp_unit; + } + + public void SetCheckSum (Guid algorithmId, byte[] checkSum) + { + } + + public void SetSource (byte[] source) + { + } + + SourceFileEntry ISourceFile.Entry { + get { return comp_unit.SourceFile; } + } + + public CompileUnitEntry Entry { + get { return comp_unit; } + } + } + + class SourceMethodImpl: IMethodDef + { + string name; + int token; + int namespaceID; + + public SourceMethodImpl (string name, int token, int namespaceID) + { + this.name = name; + this.token = token; + this.namespaceID = namespaceID; + } + + public string Name { + get { return name; } + } + + public int NamespaceID { + get { return namespaceID; } + } + + public int Token { + get { return token; } + } + } + + class NamespaceInfo + { + public string Name; + public int NamespaceID; + public ArrayList UsingClauses = new ArrayList (); + } +} + +#endif diff --git a/Mono.Cecil.Mdb/Properties/AssemblyInfo.cs b/Mono.Cecil.Mdb/Properties/AssemblyInfo.cs deleted file mode 100644 index 4ce51b25..00000000 --- a/Mono.Cecil.Mdb/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// 有关程序集的常规信息通过下列特性集 -// 控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("Mono.Cecil.Mdb")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Mono.Cecil.Mdb")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 程序集的版本信息由下面四个值组成: -// -// 主版本 -// 次版本 -// 生成号 -// 修订号 -// -// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, -// 方法是按如下所示使用“*”: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: ComVisible(false)] \ No newline at end of file diff --git a/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReader.cs b/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReader.cs deleted file mode 100644 index 4878afae..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReader.cs +++ /dev/null @@ -1,177 +0,0 @@ -using Mono.Cecil.Cil; -using Mono.Collections.Generic; -using Mono.CompilerServices.SymbolWriter; -using System; -using System.Collections.Generic; -namespace Mono.Cecil.Mdb -{ - public class MdbReader : ISymbolReader, IDisposable - { - private readonly MonoSymbolFile symbol_file; - private readonly Dictionary documents; - public MdbReader(MonoSymbolFile symFile) - { - this.symbol_file = symFile; - this.documents = new Dictionary(); - } - public bool ProcessDebugHeader(ImageDebugDirectory directory, byte[] header) - { - return true; - } - public void Read(MethodBody body, InstructionMapper mapper) - { - MetadataToken method_token = body.Method.MetadataToken; - MethodEntry entry = this.symbol_file.GetMethodByToken(method_token.ToInt32()); - if (entry != null) - { - Scope[] scopes = MdbReader.ReadScopes(entry, body, mapper); - this.ReadLineNumbers(entry, mapper); - MdbReader.ReadLocalVariables(entry, body, scopes); - } - } - private static void ReadLocalVariables(MethodEntry entry, MethodBody body, Scope[] scopes) - { - LocalVariableEntry[] locals = entry.GetLocals(); - LocalVariableEntry[] array = locals; - for (int i = 0; i < array.Length; i++) - { - LocalVariableEntry local = array[i]; - VariableDefinition variable = body.Variables[local.Index]; - variable.Name = local.Name; - int index = local.BlockIndex; - if (index >= 0 && index < scopes.Length) - { - Scope scope = scopes[index]; - if (scope != null) - { - scope.Variables.Add(variable); - } - } - } - } - private void ReadLineNumbers(MethodEntry entry, InstructionMapper mapper) - { - Document document = null; - LineNumberTable table = entry.GetLineNumberTable(); - LineNumberEntry[] lineNumbers = table.LineNumbers; - for (int i = 0; i < lineNumbers.Length; i++) - { - LineNumberEntry line = lineNumbers[i]; - Instruction instruction = mapper(line.Offset); - if (instruction != null) - { - if (document == null) - { - document = this.GetDocument(entry.CompileUnit.SourceFile); - } - instruction.SequencePoint = new SequencePoint(document) - { - StartLine = line.Row, - EndLine = line.Row - }; - } - } - } - private Document GetDocument(SourceFileEntry file) - { - string file_name = file.FileName; - Document document; - Document result; - if (this.documents.TryGetValue(file_name, out document)) - { - result = document; - } - else - { - document = new Document(file_name); - this.documents.Add(file_name, document); - result = document; - } - return result; - } - private static Scope[] ReadScopes(MethodEntry entry, MethodBody body, InstructionMapper mapper) - { - CodeBlockEntry[] blocks = entry.GetCodeBlocks(); - Scope[] scopes = new Scope[blocks.Length]; - CodeBlockEntry[] array = blocks; - for (int i = 0; i < array.Length; i++) - { - CodeBlockEntry block = array[i]; - if (block.BlockType == CodeBlockEntry.Type.Lexical) - { - Scope scope = new Scope(); - scope.Start = mapper(block.StartOffset); - scope.End = mapper(block.EndOffset); - scopes[block.Index] = scope; - if (body.Scope == null) - { - body.Scope = scope; - } - if (!MdbReader.AddScope(body.Scope, scope)) - { - body.Scope = scope; - } - } - } - return scopes; - } - private static bool AddScope(Scope provider, Scope scope) - { - bool result; - foreach (Scope sub_scope in provider.Scopes) - { - if (MdbReader.AddScope(sub_scope, scope)) - { - result = true; - return result; - } - if (scope.Start.Offset >= sub_scope.Start.Offset && scope.End.Offset <= sub_scope.End.Offset) - { - sub_scope.Scopes.Add(scope); - result = true; - return result; - } - } - result = false; - return result; - } - public void Read(MethodSymbols symbols) - { - MethodEntry entry = this.symbol_file.GetMethodByToken(symbols.MethodToken.ToInt32()); - if (entry != null) - { - this.ReadLineNumbers(entry, symbols); - MdbReader.ReadLocalVariables(entry, symbols); - } - } - private void ReadLineNumbers(MethodEntry entry, MethodSymbols symbols) - { - LineNumberTable table = entry.GetLineNumberTable(); - LineNumberEntry[] lines = table.LineNumbers; - Collection instructions = symbols.instructions = new Collection(lines.Length); - for (int i = 0; i < lines.Length; i++) - { - LineNumberEntry line = lines[i]; - instructions.Add(new InstructionSymbol(line.Offset, new SequencePoint(this.GetDocument(entry.CompileUnit.SourceFile)) - { - StartLine = line.Row, - EndLine = line.Row - })); - } - } - private static void ReadLocalVariables(MethodEntry entry, MethodSymbols symbols) - { - LocalVariableEntry[] locals = entry.GetLocals(); - for (int i = 0; i < locals.Length; i++) - { - LocalVariableEntry local = locals[i]; - VariableDefinition variable = symbols.Variables[local.Index]; - variable.Name = local.Name; - } - } - public void Dispose() - { - this.symbol_file.Dispose(); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReaderProvider.cs b/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReaderProvider.cs deleted file mode 100644 index b140e831..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReaderProvider.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Mono.Cecil.Cil; -using Mono.CompilerServices.SymbolWriter; -using System; -using System.IO; -namespace Mono.Cecil.Mdb -{ - public class MdbReaderProvider : ISymbolReaderProvider - { - public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName) - { - return new MdbReader(MonoSymbolFile.ReadSymbolFile(module, fileName)); - } - public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream) - { - return new MdbReader(MonoSymbolFile.ReadSymbolFile(module, symbolStream)); - //throw new NotImplementedException(); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/AnonymousScopeEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/AnonymousScopeEntry.cs deleted file mode 100644 index 422579ca..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/AnonymousScopeEntry.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Collections.Generic; -namespace Mono.CompilerServices.SymbolWriter -{ - public class AnonymousScopeEntry - { - public readonly int ID; - private List captured_vars = new List(); - private List captured_scopes = new List(); - public CapturedVariable[] CapturedVariables - { - get - { - CapturedVariable[] retval = new CapturedVariable[this.captured_vars.Count]; - this.captured_vars.CopyTo(retval, 0); - return retval; - } - } - public CapturedScope[] CapturedScopes - { - get - { - CapturedScope[] retval = new CapturedScope[this.captured_scopes.Count]; - this.captured_scopes.CopyTo(retval, 0); - return retval; - } - } - public AnonymousScopeEntry(int id) - { - this.ID = id; - } - internal AnonymousScopeEntry(MyBinaryReader reader) - { - this.ID = reader.ReadLeb128(); - int num_captured_vars = reader.ReadLeb128(); - for (int i = 0; i < num_captured_vars; i++) - { - this.captured_vars.Add(new CapturedVariable(reader)); - } - int num_captured_scopes = reader.ReadLeb128(); - for (int i = 0; i < num_captured_scopes; i++) - { - this.captured_scopes.Add(new CapturedScope(reader)); - } - } - internal void AddCapturedVariable(string name, string captured_name, CapturedVariable.CapturedKind kind) - { - this.captured_vars.Add(new CapturedVariable(name, captured_name, kind)); - } - internal void AddCapturedScope(int scope, string captured_name) - { - this.captured_scopes.Add(new CapturedScope(scope, captured_name)); - } - //internal void Write(MyBinaryWriter bw) - //{ - // bw.WriteLeb128(this.ID); - // bw.WriteLeb128(this.captured_vars.Count); - // foreach (CapturedVariable cv in this.captured_vars) - // { - // cv.Write(bw); - // } - // bw.WriteLeb128(this.captured_scopes.Count); - // foreach (CapturedScope cs in this.captured_scopes) - // { - // cs.Write(bw); - // } - //} - public override string ToString() - { - return string.Format("[AnonymousScope {0}]", this.ID); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedScope.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedScope.cs deleted file mode 100644 index 1669d3e7..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedScope.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -namespace Mono.CompilerServices.SymbolWriter -{ - public struct CapturedScope - { - public readonly int Scope; - public readonly string CapturedName; - public CapturedScope(int scope, string captured_name) - { - this.Scope = scope; - this.CapturedName = captured_name; - } - internal CapturedScope(MyBinaryReader reader) - { - this.Scope = reader.ReadLeb128(); - this.CapturedName = reader.ReadString(); - } - //internal void Write(MyBinaryWriter bw) - //{ - // bw.WriteLeb128(this.Scope); - // bw.Write(this.CapturedName); - //} - public override string ToString() - { - return string.Format("[CapturedScope {0}:{1}]", this.Scope, this.CapturedName); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedVariable.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedVariable.cs deleted file mode 100644 index 3740f114..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedVariable.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -namespace Mono.CompilerServices.SymbolWriter -{ - public struct CapturedVariable - { - public enum CapturedKind : byte - { - Local, - Parameter, - This - } - public readonly string Name; - public readonly string CapturedName; - public readonly CapturedVariable.CapturedKind Kind; - public CapturedVariable(string name, string captured_name, CapturedVariable.CapturedKind kind) - { - this.Name = name; - this.CapturedName = captured_name; - this.Kind = kind; - } - internal CapturedVariable(MyBinaryReader reader) - { - this.Name = reader.ReadString(); - this.CapturedName = reader.ReadString(); - this.Kind = (CapturedVariable.CapturedKind)reader.ReadByte(); - } - //internal void Write(MyBinaryWriter bw) - //{ - // bw.Write(this.Name); - // bw.Write(this.CapturedName); - // bw.Write((byte)this.Kind); - //} - public override string ToString() - { - return string.Format("[CapturedVariable {0}:{1}:{2}]", this.Name, this.CapturedName, this.Kind); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CodeBlockEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CodeBlockEntry.cs deleted file mode 100644 index 91f51d9c..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CodeBlockEntry.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -namespace Mono.CompilerServices.SymbolWriter -{ - public class CodeBlockEntry - { - public enum Type - { - Lexical = 1, - CompilerGenerated, - IteratorBody, - IteratorDispatcher - } - public int Index; - public int Parent; - public CodeBlockEntry.Type BlockType; - public int StartOffset; - public int EndOffset; - public CodeBlockEntry(int index, int parent, CodeBlockEntry.Type type, int start_offset) - { - this.Index = index; - this.Parent = parent; - this.BlockType = type; - this.StartOffset = start_offset; - } - internal CodeBlockEntry(int index, MyBinaryReader reader) - { - this.Index = index; - int type_flag = reader.ReadLeb128(); - this.BlockType = (CodeBlockEntry.Type)(type_flag & 63); - this.Parent = reader.ReadLeb128(); - this.StartOffset = reader.ReadLeb128(); - this.EndOffset = reader.ReadLeb128(); - if ((type_flag & 64) != 0) - { - int data_size = (int)reader.ReadInt16(); - reader.BaseStream.Position += (long)data_size; - } - } - public void Close(int end_offset) - { - this.EndOffset = end_offset; - } - //internal void Write(MyBinaryWriter bw) - //{ - // bw.WriteLeb128((int)this.BlockType); - // bw.WriteLeb128(this.Parent); - // bw.WriteLeb128(this.StartOffset); - // bw.WriteLeb128(this.EndOffset); - //} - public override string ToString() - { - return string.Format("[CodeBlock {0}:{1}:{2}:{3}:{4}]", new object[] - { - this.Index, - this.Parent, - this.BlockType, - this.StartOffset, - this.EndOffset - }); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CompileUnitEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CompileUnitEntry.cs deleted file mode 100644 index 1c150817..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CompileUnitEntry.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -namespace Mono.CompilerServices.SymbolWriter -{ - public class CompileUnitEntry : ICompileUnit - { - public readonly int Index; - private int DataOffset; - private MonoSymbolFile file; - private SourceFileEntry source; - private List include_files; - private List namespaces; - private bool creating; - public static int Size - { - get - { - return 8; - } - } - CompileUnitEntry ICompileUnit.Entry - { - get - { - return this; - } - } - public SourceFileEntry SourceFile - { - get - { - SourceFileEntry result; - if (this.creating) - { - result = this.source; - } - else - { - this.ReadData(); - result = this.source; - } - return result; - } - } - public NamespaceEntry[] Namespaces - { - get - { - this.ReadData(); - NamespaceEntry[] retval = new NamespaceEntry[this.namespaces.Count]; - this.namespaces.CopyTo(retval, 0); - return retval; - } - } - public SourceFileEntry[] IncludeFiles - { - get - { - this.ReadData(); - SourceFileEntry[] result; - if (this.include_files == null) - { - result = new SourceFileEntry[0]; - } - else - { - SourceFileEntry[] retval = new SourceFileEntry[this.include_files.Count]; - this.include_files.CopyTo(retval, 0); - result = retval; - } - return result; - } - } - public CompileUnitEntry(MonoSymbolFile file, SourceFileEntry source) - { - this.file = file; - this.source = source; - this.Index = file.AddCompileUnit(this); - this.creating = true; - this.namespaces = new List(); - } - public void AddFile(SourceFileEntry file) - { - if (!this.creating) - { - throw new InvalidOperationException(); - } - if (this.include_files == null) - { - this.include_files = new List(); - } - this.include_files.Add(file); - } - public int DefineNamespace(string name, string[] using_clauses, int parent) - { - if (!this.creating) - { - throw new InvalidOperationException(); - } - int index = this.file.GetNextNamespaceIndex(); - NamespaceEntry ns = new NamespaceEntry(name, index, using_clauses, parent); - this.namespaces.Add(ns); - return index; - } - //internal void WriteData(MyBinaryWriter bw) - //{ - // this.DataOffset = (int)bw.BaseStream.Position; - // bw.WriteLeb128(this.source.Index); - // int count_includes = (this.include_files != null) ? this.include_files.Count : 0; - // bw.WriteLeb128(count_includes); - // if (this.include_files != null) - // { - // foreach (SourceFileEntry entry in this.include_files) - // { - // bw.WriteLeb128(entry.Index); - // } - // } - // bw.WriteLeb128(this.namespaces.Count); - // foreach (NamespaceEntry ns in this.namespaces) - // { - // ns.Write(this.file, bw); - // } - //} - //internal void Write(BinaryWriter bw) - //{ - // bw.Write(this.Index); - // bw.Write(this.DataOffset); - //} - internal CompileUnitEntry(MonoSymbolFile file, MyBinaryReader reader) - { - this.file = file; - this.Index = reader.ReadInt32(); - this.DataOffset = reader.ReadInt32(); - } - private void ReadData() - { - if (this.creating) - { - throw new InvalidOperationException(); - } - lock (this.file) - { - if (this.namespaces == null) - { - MyBinaryReader reader = this.file.BinaryReader; - int old_pos = (int)reader.BaseStream.Position; - reader.BaseStream.Position = (long)this.DataOffset; - int source_idx = reader.ReadLeb128(); - this.source = this.file.GetSourceFile(source_idx); - int count_includes = reader.ReadLeb128(); - if (count_includes > 0) - { - this.include_files = new List(); - for (int i = 0; i < count_includes; i++) - { - this.include_files.Add(this.file.GetSourceFile(reader.ReadLeb128())); - } - } - int count_ns = reader.ReadLeb128(); - this.namespaces = new List(); - for (int i = 0; i < count_ns; i++) - { - this.namespaces.Add(new NamespaceEntry(this.file, reader)); - } - reader.BaseStream.Position = (long)old_pos; - } - } - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ICompileUnit.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ICompileUnit.cs deleted file mode 100644 index ea35a71e..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ICompileUnit.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -namespace Mono.CompilerServices.SymbolWriter -{ - public interface ICompileUnit - { - CompileUnitEntry Entry - { - get; - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/IMethodDef.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/IMethodDef.cs deleted file mode 100644 index 60999589..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/IMethodDef.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -namespace Mono.CompilerServices.SymbolWriter -{ - public interface IMethodDef - { - string Name - { - get; - } - int Token - { - get; - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ISourceFile.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ISourceFile.cs deleted file mode 100644 index ee0b6f77..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ISourceFile.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -namespace Mono.CompilerServices.SymbolWriter -{ - public interface ISourceFile - { - SourceFileEntry Entry - { - get; - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberEntry.cs deleted file mode 100644 index 2144cc7f..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberEntry.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections.Generic; -namespace Mono.CompilerServices.SymbolWriter -{ - public class LineNumberEntry - { - private class OffsetComparerClass : IComparer - { - public int Compare(LineNumberEntry l1, LineNumberEntry l2) - { - int result; - if (l1.Offset < l2.Offset) - { - result = -1; - } - else - { - if (l1.Offset > l2.Offset) - { - result = 1; - } - else - { - result = 0; - } - } - return result; - } - } - private class RowComparerClass : IComparer - { - public int Compare(LineNumberEntry l1, LineNumberEntry l2) - { - int result; - if (l1.Row < l2.Row) - { - result = -1; - } - else - { - if (l1.Row > l2.Row) - { - result = 1; - } - else - { - result = 0; - } - } - return result; - } - } - public readonly int Row; - public readonly int File; - public readonly int Offset; - public readonly bool IsHidden; - public static LineNumberEntry Null = new LineNumberEntry(0, 0, 0); - public static readonly IComparer OffsetComparer = new LineNumberEntry.OffsetComparerClass(); - public static readonly IComparer RowComparer = new LineNumberEntry.RowComparerClass(); - public LineNumberEntry(int file, int row, int offset) : this(file, row, offset, false) - { - } - public LineNumberEntry(int file, int row, int offset, bool is_hidden) - { - this.File = file; - this.Row = row; - this.Offset = offset; - this.IsHidden = is_hidden; - } - public override string ToString() - { - return string.Format("[Line {0}:{1}:{2}]", this.File, this.Row, this.Offset); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberTable.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberTable.cs deleted file mode 100644 index 2a3b56d5..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberTable.cs +++ /dev/null @@ -1,233 +0,0 @@ -using System; -using System.Collections.Generic; -namespace Mono.CompilerServices.SymbolWriter -{ - public class LineNumberTable - { - public const int Default_LineBase = -1; - public const int Default_LineRange = 8; - public const byte Default_OpcodeBase = 9; - public const bool SuppressDuplicates = true; - public const byte DW_LNS_copy = 1; - public const byte DW_LNS_advance_pc = 2; - public const byte DW_LNS_advance_line = 3; - public const byte DW_LNS_set_file = 4; - public const byte DW_LNS_const_add_pc = 8; - public const byte DW_LNE_end_sequence = 1; - public const byte DW_LNE_MONO_negate_is_hidden = 64; - internal const byte DW_LNE_MONO__extensions_start = 64; - internal const byte DW_LNE_MONO__extensions_end = 127; - protected LineNumberEntry[] _line_numbers; - public readonly int LineBase; - public readonly int LineRange; - public readonly byte OpcodeBase; - public readonly int MaxAddressIncrement; - public LineNumberEntry[] LineNumbers - { - get - { - return this._line_numbers; - } - } - protected LineNumberTable(MonoSymbolFile file) - { - this.LineBase = file.OffsetTable.LineNumberTable_LineBase; - this.LineRange = file.OffsetTable.LineNumberTable_LineRange; - this.OpcodeBase = (byte)file.OffsetTable.LineNumberTable_OpcodeBase; - this.MaxAddressIncrement = (int)(255 - this.OpcodeBase) / this.LineRange; - } - internal LineNumberTable(MonoSymbolFile file, LineNumberEntry[] lines) : this(file) - { - this._line_numbers = lines; - } - //internal void Write(MonoSymbolFile file, MyBinaryWriter bw) - //{ - // int start = (int)bw.BaseStream.Position; - // bool last_is_hidden = false; - // int last_line = 1; - // int last_offset = 0; - // int last_file = 1; - // int i = 0; - // while (i < this.LineNumbers.Length) - // { - // int line_inc = this.LineNumbers[i].Row - last_line; - // int offset_inc = this.LineNumbers[i].Offset - last_offset; - // if (i + 1 >= this.LineNumbers.Length) - // { - // goto IL_84; - // } - // if (!this.LineNumbers[i + 1].Equals(this.LineNumbers[i])) - // { - // goto IL_84; - // } - // IL_207: - // i++; - // continue; - // IL_84: - // if (this.LineNumbers[i].File != last_file) - // { - // bw.Write(4); - // bw.WriteLeb128(this.LineNumbers[i].File); - // last_file = this.LineNumbers[i].File; - // } - // if (this.LineNumbers[i].IsHidden != last_is_hidden) - // { - // bw.Write(0); - // bw.Write(1); - // bw.Write(64); - // last_is_hidden = this.LineNumbers[i].IsHidden; - // } - // if (offset_inc >= this.MaxAddressIncrement) - // { - // if (offset_inc < 2 * this.MaxAddressIncrement) - // { - // bw.Write(8); - // offset_inc -= this.MaxAddressIncrement; - // } - // else - // { - // bw.Write(2); - // bw.WriteLeb128(offset_inc); - // offset_inc = 0; - // } - // } - // if (line_inc < this.LineBase || line_inc >= this.LineBase + this.LineRange) - // { - // bw.Write(3); - // bw.WriteLeb128(line_inc); - // if (offset_inc != 0) - // { - // bw.Write(2); - // bw.WriteLeb128(offset_inc); - // } - // bw.Write(1); - // } - // else - // { - // byte opcode = (byte)(line_inc - this.LineBase + this.LineRange * offset_inc + (int)this.OpcodeBase); - // bw.Write(opcode); - // } - // last_line = this.LineNumbers[i].Row; - // last_offset = this.LineNumbers[i].Offset; - // goto IL_207; - // } - // bw.Write(0); - // bw.Write(1); - // bw.Write(1); - // file.ExtendedLineNumberSize += (int)bw.BaseStream.Position - start; - //} - internal static LineNumberTable Read(MonoSymbolFile file, MyBinaryReader br) - { - LineNumberTable lnt = new LineNumberTable(file); - lnt.DoRead(file, br); - return lnt; - } - private void DoRead(MonoSymbolFile file, MyBinaryReader br) - { - List lines = new List(); - bool is_hidden = false; - bool modified = false; - int stm_line = 1; - int stm_offset = 0; - int stm_file = 1; - byte opcode; - while (true) - { - opcode = br.ReadByte(); - if (opcode == 0) - { - byte size = br.ReadByte(); - long end_pos = br.BaseStream.Position + (long)((ulong)size); - opcode = br.ReadByte(); - if (opcode == 1) - { - break; - } - if (opcode == 64) - { - is_hidden = !is_hidden; - modified = true; - } - else - { - if (opcode < 64 || opcode > 127) - { - goto IL_B8; - } - } - br.BaseStream.Position = end_pos; - } - else - { - if (opcode < this.OpcodeBase) - { - switch (opcode) - { - case 1: - lines.Add(new LineNumberEntry(stm_file, stm_line, stm_offset, is_hidden)); - modified = false; - continue; - case 2: - stm_offset += br.ReadLeb128(); - modified = true; - continue; - case 3: - stm_line += br.ReadLeb128(); - modified = true; - continue; - case 4: - stm_file = br.ReadLeb128(); - modified = true; - continue; - case 8: - stm_offset += this.MaxAddressIncrement; - modified = true; - continue; - } - goto Block_8; - } - opcode -= this.OpcodeBase; - stm_offset += (int)opcode / this.LineRange; - stm_line += this.LineBase + (int)opcode % this.LineRange; - lines.Add(new LineNumberEntry(stm_file, stm_line, stm_offset, is_hidden)); - modified = false; - } - } - if (modified) - { - lines.Add(new LineNumberEntry(stm_file, stm_line, stm_offset, is_hidden)); - } - this._line_numbers = new LineNumberEntry[lines.Count]; - lines.CopyTo(this._line_numbers, 0); - return; - IL_B8: - throw new MonoSymbolFileException("Unknown extended opcode {0:x} in LNT ({1})", new object[] - { - opcode, - file.FileName - }); - Block_8: - throw new MonoSymbolFileException("Unknown standard opcode {0:x} in LNT", new object[] - { - opcode - }); - } - public bool GetMethodBounds(out LineNumberEntry start, out LineNumberEntry end) - { - bool result; - if (this._line_numbers.Length > 1) - { - start = this._line_numbers[0]; - end = this._line_numbers[this._line_numbers.Length - 1]; - result = true; - } - else - { - start = LineNumberEntry.Null; - end = LineNumberEntry.Null; - result = false; - } - return result; - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LocalVariableEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LocalVariableEntry.cs deleted file mode 100644 index 56cc8223..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LocalVariableEntry.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -namespace Mono.CompilerServices.SymbolWriter -{ - public struct LocalVariableEntry - { - public readonly int Index; - public readonly string Name; - public readonly int BlockIndex; - public LocalVariableEntry(int index, string name, int block) - { - this.Index = index; - this.Name = name; - this.BlockIndex = block; - } - internal LocalVariableEntry(MonoSymbolFile file, MyBinaryReader reader) - { - this.Index = reader.ReadLeb128(); - this.Name = reader.ReadString(); - this.BlockIndex = reader.ReadLeb128(); - } - //internal void Write(MonoSymbolFile file, MyBinaryWriter bw) - //{ - // bw.WriteLeb128(this.Index); - // bw.Write(this.Name); - // bw.WriteLeb128(this.BlockIndex); - //} - public override string ToString() - { - return string.Format("[LocalVariable {0}:{1}:{2}]", this.Name, this.Index, this.BlockIndex - 1); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MethodEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MethodEntry.cs deleted file mode 100644 index c0e876e8..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MethodEntry.cs +++ /dev/null @@ -1,385 +0,0 @@ -using System; -using System.Collections.Generic; -namespace Mono.CompilerServices.SymbolWriter -{ - public class MethodEntry : IComparable - { - [Flags] - public enum Flags - { - LocalNamesAmbiguous = 1 - } - public const int Size = 12; - public readonly int CompileUnitIndex; - public readonly int Token; - public readonly int NamespaceID; - private int DataOffset; - private int LocalVariableTableOffset; - private int LineNumberTableOffset; - private int CodeBlockTableOffset; - private int ScopeVariableTableOffset; - private int RealNameOffset; - private MethodEntry.Flags flags; - private int index; - public readonly CompileUnitEntry CompileUnit; - private LocalVariableEntry[] locals; - private CodeBlockEntry[] code_blocks; - private ScopeVariable[] scope_vars; - private LineNumberTable lnt; - private string real_name; - public readonly MonoSymbolFile SymbolFile; - public MethodEntry.Flags MethodFlags - { - get - { - return this.flags; - } - } - public int Index - { - get - { - return this.index; - } - set - { - this.index = value; - } - } - internal MethodEntry(MonoSymbolFile file, MyBinaryReader reader, int index) - { - this.SymbolFile = file; - this.index = index; - this.Token = reader.ReadInt32(); - this.DataOffset = reader.ReadInt32(); - this.LineNumberTableOffset = reader.ReadInt32(); - long old_pos = reader.BaseStream.Position; - reader.BaseStream.Position = (long)this.DataOffset; - this.CompileUnitIndex = reader.ReadLeb128(); - this.LocalVariableTableOffset = reader.ReadLeb128(); - this.NamespaceID = reader.ReadLeb128(); - this.CodeBlockTableOffset = reader.ReadLeb128(); - this.ScopeVariableTableOffset = reader.ReadLeb128(); - this.RealNameOffset = reader.ReadLeb128(); - this.flags = (MethodEntry.Flags)reader.ReadLeb128(); - reader.BaseStream.Position = old_pos; - this.CompileUnit = file.GetCompileUnit(this.CompileUnitIndex); - } - internal MethodEntry(MonoSymbolFile file, CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, MethodEntry.Flags flags, int namespace_id) - { - this.SymbolFile = file; - this.real_name = real_name; - this.locals = locals; - this.code_blocks = code_blocks; - this.scope_vars = scope_vars; - this.flags = flags; - this.index = -1; - this.Token = token; - this.CompileUnitIndex = comp_unit.Index; - this.CompileUnit = comp_unit; - this.NamespaceID = namespace_id; - this.CheckLineNumberTable(lines); - this.lnt = new LineNumberTable(file, lines); - file.NumLineNumbers += lines.Length; - int num_locals = (locals != null) ? locals.Length : 0; - if (num_locals <= 32) - { - for (int i = 0; i < num_locals; i++) - { - string nm = locals[i].Name; - for (int j = i + 1; j < num_locals; j++) - { - if (locals[j].Name == nm) - { - flags |= MethodEntry.Flags.LocalNamesAmbiguous; - goto IL_108; - } - } - } - IL_108:; - } - else - { - Dictionary local_names = new Dictionary(); - for (int k = 0; k < locals.Length; k++) - { - LocalVariableEntry local = locals[k]; - if (local_names.ContainsKey(local.Name)) - { - flags |= MethodEntry.Flags.LocalNamesAmbiguous; - break; - } - local_names.Add(local.Name, local); - } - } - } - private void CheckLineNumberTable(LineNumberEntry[] line_numbers) - { - int last_offset = -1; - int last_row = -1; - if (line_numbers != null) - { - for (int i = 0; i < line_numbers.Length; i++) - { - LineNumberEntry line = line_numbers[i]; - if (line.Equals(LineNumberEntry.Null)) - { - throw new MonoSymbolFileException(); - } - if (line.Offset < last_offset) - { - throw new MonoSymbolFileException(); - } - if (line.Offset > last_offset) - { - last_row = line.Row; - last_offset = line.Offset; - } - else - { - if (line.Row > last_row) - { - last_row = line.Row; - } - } - } - } - } - //internal void Write(MyBinaryWriter bw) - //{ - // if (this.index <= 0 || this.DataOffset == 0) - // { - // throw new InvalidOperationException(); - // } - // bw.Write(this.Token); - // bw.Write(this.DataOffset); - // bw.Write(this.LineNumberTableOffset); - //} - //internal void WriteData(MonoSymbolFile file, MyBinaryWriter bw) - //{ - // if (this.index <= 0) - // { - // throw new InvalidOperationException(); - // } - // this.LocalVariableTableOffset = (int)bw.BaseStream.Position; - // int num_locals = (this.locals != null) ? this.locals.Length : 0; - // bw.WriteLeb128(num_locals); - // for (int i = 0; i < num_locals; i++) - // { - // this.locals[i].Write(file, bw); - // } - // file.LocalCount += num_locals; - // this.CodeBlockTableOffset = (int)bw.BaseStream.Position; - // int num_code_blocks = (this.code_blocks != null) ? this.code_blocks.Length : 0; - // bw.WriteLeb128(num_code_blocks); - // for (int i = 0; i < num_code_blocks; i++) - // { - // this.code_blocks[i].Write(bw); - // } - // this.ScopeVariableTableOffset = (int)bw.BaseStream.Position; - // int num_scope_vars = (this.scope_vars != null) ? this.scope_vars.Length : 0; - // bw.WriteLeb128(num_scope_vars); - // for (int i = 0; i < num_scope_vars; i++) - // { - // this.scope_vars[i].Write(bw); - // } - // if (this.real_name != null) - // { - // this.RealNameOffset = (int)bw.BaseStream.Position; - // bw.Write(this.real_name); - // } - // this.LineNumberTableOffset = (int)bw.BaseStream.Position; - // this.lnt.Write(file, bw); - // this.DataOffset = (int)bw.BaseStream.Position; - // bw.WriteLeb128(this.CompileUnitIndex); - // bw.WriteLeb128(this.LocalVariableTableOffset); - // bw.WriteLeb128(this.NamespaceID); - // bw.WriteLeb128(this.CodeBlockTableOffset); - // bw.WriteLeb128(this.ScopeVariableTableOffset); - // bw.WriteLeb128(this.RealNameOffset); - // bw.WriteLeb128((int)this.flags); - //} - public LineNumberTable GetLineNumberTable() - { - LineNumberTable result; - lock (this.SymbolFile) - { - if (this.lnt != null) - { - result = this.lnt; - } - else - { - if (this.LineNumberTableOffset == 0) - { - result = null; - } - else - { - MyBinaryReader reader = this.SymbolFile.BinaryReader; - long old_pos = reader.BaseStream.Position; - reader.BaseStream.Position = (long)this.LineNumberTableOffset; - this.lnt = LineNumberTable.Read(this.SymbolFile, reader); - reader.BaseStream.Position = old_pos; - result = this.lnt; - } - } - } - return result; - } - public LocalVariableEntry[] GetLocals() - { - LocalVariableEntry[] result; - lock (this.SymbolFile) - { - if (this.locals != null) - { - result = this.locals; - } - else - { - if (this.LocalVariableTableOffset == 0) - { - result = null; - } - else - { - MyBinaryReader reader = this.SymbolFile.BinaryReader; - long old_pos = reader.BaseStream.Position; - reader.BaseStream.Position = (long)this.LocalVariableTableOffset; - int num_locals = reader.ReadLeb128(); - this.locals = new LocalVariableEntry[num_locals]; - for (int i = 0; i < num_locals; i++) - { - this.locals[i] = new LocalVariableEntry(this.SymbolFile, reader); - } - reader.BaseStream.Position = old_pos; - result = this.locals; - } - } - } - return result; - } - public CodeBlockEntry[] GetCodeBlocks() - { - CodeBlockEntry[] result; - lock (this.SymbolFile) - { - if (this.code_blocks != null) - { - result = this.code_blocks; - } - else - { - if (this.CodeBlockTableOffset == 0) - { - result = null; - } - else - { - MyBinaryReader reader = this.SymbolFile.BinaryReader; - long old_pos = reader.BaseStream.Position; - reader.BaseStream.Position = (long)this.CodeBlockTableOffset; - int num_code_blocks = reader.ReadLeb128(); - this.code_blocks = new CodeBlockEntry[num_code_blocks]; - for (int i = 0; i < num_code_blocks; i++) - { - this.code_blocks[i] = new CodeBlockEntry(i, reader); - } - reader.BaseStream.Position = old_pos; - result = this.code_blocks; - } - } - } - return result; - } - public ScopeVariable[] GetScopeVariables() - { - ScopeVariable[] result; - lock (this.SymbolFile) - { - if (this.scope_vars != null) - { - result = this.scope_vars; - } - else - { - if (this.ScopeVariableTableOffset == 0) - { - result = null; - } - else - { - MyBinaryReader reader = this.SymbolFile.BinaryReader; - long old_pos = reader.BaseStream.Position; - reader.BaseStream.Position = (long)this.ScopeVariableTableOffset; - int num_scope_vars = reader.ReadLeb128(); - this.scope_vars = new ScopeVariable[num_scope_vars]; - for (int i = 0; i < num_scope_vars; i++) - { - this.scope_vars[i] = new ScopeVariable(reader); - } - reader.BaseStream.Position = old_pos; - result = this.scope_vars; - } - } - } - return result; - } - public string GetRealName() - { - string result; - lock (this.SymbolFile) - { - if (this.real_name != null) - { - result = this.real_name; - } - else - { - if (this.RealNameOffset == 0) - { - result = null; - } - else - { - this.real_name = this.SymbolFile.BinaryReader.ReadString(this.RealNameOffset); - result = this.real_name; - } - } - } - return result; - } - public int CompareTo(object obj) - { - MethodEntry method = (MethodEntry)obj; - int result; - if (method.Token < this.Token) - { - result = 1; - } - else - { - if (method.Token > this.Token) - { - result = -1; - } - else - { - result = 0; - } - } - return result; - } - public override string ToString() - { - return string.Format("[Method {0}:{1:x}:{2}:{3}]", new object[] - { - this.index, - this.Token, - this.CompileUnitIndex, - this.CompileUnit - }); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs deleted file mode 100644 index 2204cace..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs +++ /dev/null @@ -1,635 +0,0 @@ -using Mono.Cecil; -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading; -namespace Mono.CompilerServices.SymbolWriter -{ - public class MonoSymbolFile : IDisposable - { - private List methods = new List(); - private List sources = new List(); - private List comp_units = new List(); - private Dictionary type_hash = new Dictionary(); - private Dictionary anonymous_scopes; - private OffsetTable ot; - private int last_type_index; - private int last_method_index; - private int last_namespace_index; - public readonly string FileName = ""; - public readonly int MajorVersion = 50; - public readonly int MinorVersion = 0; - public int NumLineNumbers; - private MyBinaryReader reader; - private Dictionary source_file_hash; - private Dictionary compile_unit_hash; - private List method_list; - private Dictionary method_token_hash; - private Dictionary source_name_hash; - private Guid guid; - internal int LineNumberCount = 0; - internal int LocalCount = 0; - internal int StringSize = 0; - internal int LineNumberSize = 0; - internal int ExtendedLineNumberSize = 0; - public int CompileUnitCount - { - get - { - return this.ot.CompileUnitCount; - } - } - public int SourceCount - { - get - { - return this.ot.SourceCount; - } - } - public int MethodCount - { - get - { - return this.ot.MethodCount; - } - } - public int TypeCount - { - get - { - return this.ot.TypeCount; - } - } - public int AnonymousScopeCount - { - get - { - return this.ot.AnonymousScopeCount; - } - } - public int NamespaceCount - { - get - { - return this.last_namespace_index; - } - } - public Guid Guid - { - get - { - return this.guid; - } - } - public OffsetTable OffsetTable - { - get - { - return this.ot; - } - } - public SourceFileEntry[] Sources - { - get - { - if (this.reader == null) - { - throw new InvalidOperationException(); - } - SourceFileEntry[] retval = new SourceFileEntry[this.SourceCount]; - for (int i = 0; i < this.SourceCount; i++) - { - retval[i] = this.GetSourceFile(i + 1); - } - return retval; - } - } - public CompileUnitEntry[] CompileUnits - { - get - { - if (this.reader == null) - { - throw new InvalidOperationException(); - } - CompileUnitEntry[] retval = new CompileUnitEntry[this.CompileUnitCount]; - for (int i = 0; i < this.CompileUnitCount; i++) - { - retval[i] = this.GetCompileUnit(i + 1); - } - return retval; - } - } - public MethodEntry[] Methods - { - get - { - if (this.reader == null) - { - throw new InvalidOperationException(); - } - bool flag = false; - MethodEntry[] result; - - this.read_methods(); - MethodEntry[] retval = new MethodEntry[this.MethodCount]; - this.method_list.CopyTo(retval, 0); - result = retval; - - return result; - } - } - internal MyBinaryReader BinaryReader - { - get - { - if (this.reader == null) - { - throw new InvalidOperationException(); - } - return this.reader; - } - } - internal MonoSymbolFile() - { - this.ot = new OffsetTable(); - } - internal int AddSource(SourceFileEntry source) - { - this.sources.Add(source); - return this.sources.Count; - } - internal int AddCompileUnit(CompileUnitEntry entry) - { - this.comp_units.Add(entry); - return this.comp_units.Count; - } - internal int DefineType(Type type) - { - int index; - int result; - if (this.type_hash.TryGetValue(type, out index)) - { - result = index; - } - else - { - index = ++this.last_type_index; - this.type_hash.Add(type, index); - result = index; - } - return result; - } - internal void AddMethod(MethodEntry entry) - { - this.methods.Add(entry); - } - public MethodEntry DefineMethod(CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, MethodEntry.Flags flags, int namespace_id) - { - if (this.reader != null) - { - throw new InvalidOperationException(); - } - MethodEntry method = new MethodEntry(this, comp_unit, token, scope_vars, locals, lines, code_blocks, real_name, flags, namespace_id); - this.AddMethod(method); - return method; - } - internal void DefineAnonymousScope(int id) - { - if (this.reader != null) - { - throw new InvalidOperationException(); - } - if (this.anonymous_scopes == null) - { - this.anonymous_scopes = new Dictionary(); - } - this.anonymous_scopes.Add(id, new AnonymousScopeEntry(id)); - } - internal void DefineCapturedVariable(int scope_id, string name, string captured_name, CapturedVariable.CapturedKind kind) - { - if (this.reader != null) - { - throw new InvalidOperationException(); - } - AnonymousScopeEntry scope = this.anonymous_scopes[scope_id]; - scope.AddCapturedVariable(name, captured_name, kind); - } - internal void DefineCapturedScope(int scope_id, int id, string captured_name) - { - if (this.reader != null) - { - throw new InvalidOperationException(); - } - AnonymousScopeEntry scope = this.anonymous_scopes[scope_id]; - scope.AddCapturedScope(id, captured_name); - } - internal int GetNextTypeIndex() - { - return ++this.last_type_index; - } - internal int GetNextMethodIndex() - { - return ++this.last_method_index; - } - internal int GetNextNamespaceIndex() - { - return ++this.last_namespace_index; - } - //private void Write(MyBinaryWriter bw, Guid guid) - //{ - // bw.Write(5037318119232611860L); - // bw.Write(this.MajorVersion); - // bw.Write(this.MinorVersion); - // bw.Write(guid.ToByteArray()); - // long offset_table_offset = bw.BaseStream.Position; - // this.ot.Write(bw, this.MajorVersion, this.MinorVersion); - // this.methods.Sort(); - // for (int i = 0; i < this.methods.Count; i++) - // { - // this.methods[i].Index = i + 1; - // } - // this.ot.DataSectionOffset = (int)bw.BaseStream.Position; - // foreach (SourceFileEntry source in this.sources) - // { - // //SourceFileEntry source; - // source.WriteData(bw); - // } - // foreach (CompileUnitEntry comp_unit in this.comp_units) - // { - // comp_unit.WriteData(bw); - // } - // foreach (MethodEntry method in this.methods) - // { - // method.WriteData(this, bw); - // } - // this.ot.DataSectionSize = (int)bw.BaseStream.Position - this.ot.DataSectionOffset; - // this.ot.MethodTableOffset = (int)bw.BaseStream.Position; - // for (int i = 0; i < this.methods.Count; i++) - // { - // MethodEntry entry = this.methods[i]; - // entry.Write(bw); - // } - // this.ot.MethodTableSize = (int)bw.BaseStream.Position - this.ot.MethodTableOffset; - // this.ot.SourceTableOffset = (int)bw.BaseStream.Position; - // for (int i = 0; i < this.sources.Count; i++) - // { - // SourceFileEntry source = this.sources[i]; - // source.Write(bw); - // } - // this.ot.SourceTableSize = (int)bw.BaseStream.Position - this.ot.SourceTableOffset; - // this.ot.CompileUnitTableOffset = (int)bw.BaseStream.Position; - // for (int i = 0; i < this.comp_units.Count; i++) - // { - // CompileUnitEntry unit = this.comp_units[i]; - // unit.Write(bw); - // } - // this.ot.CompileUnitTableSize = (int)bw.BaseStream.Position - this.ot.CompileUnitTableOffset; - // this.ot.AnonymousScopeCount = ((this.anonymous_scopes != null) ? this.anonymous_scopes.Count : 0); - // this.ot.AnonymousScopeTableOffset = (int)bw.BaseStream.Position; - // if (this.anonymous_scopes != null) - // { - // foreach (AnonymousScopeEntry scope in this.anonymous_scopes.Values) - // { - // scope.Write(bw); - // } - // } - // this.ot.AnonymousScopeTableSize = (int)bw.BaseStream.Position - this.ot.AnonymousScopeTableOffset; - // this.ot.TypeCount = this.last_type_index; - // this.ot.MethodCount = this.methods.Count; - // this.ot.SourceCount = this.sources.Count; - // this.ot.CompileUnitCount = this.comp_units.Count; - // this.ot.TotalFileSize = (int)bw.BaseStream.Position; - // bw.Seek((int)offset_table_offset, SeekOrigin.Begin); - // this.ot.Write(bw, this.MajorVersion, this.MinorVersion); - // bw.Seek(0, SeekOrigin.End); - //} - //public void CreateSymbolFile(Guid guid, FileStream fs) - //{ - // if (this.reader != null) - // { - // throw new InvalidOperationException(); - // } - // this.Write(new MyBinaryWriter(fs), guid); - //} - private MonoSymbolFile(System.IO.Stream stream) - { - //this.FileName = filename; - //FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read); - this.reader = new MyBinaryReader(stream); - try - { - long magic = this.reader.ReadInt64(); - int major_version = this.reader.ReadInt32(); - int minor_version = this.reader.ReadInt32(); - if (magic != 5037318119232611860L) - { - throw new MonoSymbolFileException("Symbol file `{0}' is not a valid Mono symbol file", new object[] - { - //filename - }); - } - if (major_version != 50) - { - throw new MonoSymbolFileException("Symbol file `{0}' has version {1}, but expected {2}", new object[] - { - //filename, - major_version, - 50 - }); - } - if (minor_version != 0) - { - throw new MonoSymbolFileException("Symbol file `{0}' has version {1}.{2}, but expected {3}.{4}", new object[] - { - //filename, - major_version, - minor_version, - 50, - 0 - }); - } - this.MajorVersion = major_version; - this.MinorVersion = minor_version; - this.guid = new Guid(this.reader.ReadBytes(16)); - this.ot = new OffsetTable(this.reader, major_version, minor_version); - } - catch - { - throw new MonoSymbolFileException("Cannot read symbol file `{0}'", new object[] - { - //filename - }); - } - this.source_file_hash = new Dictionary(); - this.compile_unit_hash = new Dictionary(); - } - private MonoSymbolFile(string filename) - { - this.FileName = filename; - FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read); - this.reader = new MyBinaryReader(stream); - try - { - long magic = this.reader.ReadInt64(); - int major_version = this.reader.ReadInt32(); - int minor_version = this.reader.ReadInt32(); - if (magic != 5037318119232611860L) - { - throw new MonoSymbolFileException("Symbol file `{0}' is not a valid Mono symbol file", new object[] - { - filename - }); - } - if (major_version != 50) - { - throw new MonoSymbolFileException("Symbol file `{0}' has version {1}, but expected {2}", new object[] - { - filename, - major_version, - 50 - }); - } - if (minor_version != 0) - { - throw new MonoSymbolFileException("Symbol file `{0}' has version {1}.{2}, but expected {3}.{4}", new object[] - { - filename, - major_version, - minor_version, - 50, - 0 - }); - } - this.MajorVersion = major_version; - this.MinorVersion = minor_version; - this.guid = new Guid(this.reader.ReadBytes(16)); - this.ot = new OffsetTable(this.reader, major_version, minor_version); - } - catch - { - throw new MonoSymbolFileException("Cannot read symbol file `{0}'", new object[] - { - filename - }); - } - this.source_file_hash = new Dictionary(); - this.compile_unit_hash = new Dictionary(); - } - private void CheckGuidMatch(Guid other, string filename, string assembly) - { - if (other == this.guid) - { - return; - } - throw new MonoSymbolFileException("Symbol file `{0}' does not match assembly `{1}'", new object[] - { - filename, - assembly - }); - } - protected MonoSymbolFile(string filename, ModuleDefinition module) - : this(filename) - { - if (module != null) - { - this.CheckGuidMatch(module.Mvid, filename, module.FullyQualifiedName); - } - } - protected MonoSymbolFile(System.IO.Stream stream, ModuleDefinition module) - : this(stream) - { - if (module != null) - { - //this.CheckGuidMatch(module.Mvid, filename, module.FullyQualifiedName); - } - } - public static MonoSymbolFile ReadSymbolFile(ModuleDefinition module) - { - return MonoSymbolFile.ReadSymbolFile(module, module.FullyQualifiedName); - } - public static MonoSymbolFile ReadSymbolFile(ModuleDefinition module, string filename) - { - string name = filename + ".mdb"; - return new MonoSymbolFile(name, module); - } - public static MonoSymbolFile ReadSymbolFile(ModuleDefinition module, System.IO.Stream stream) - { - return new MonoSymbolFile(stream, module); - } - public static MonoSymbolFile ReadSymbolFile(string mdbFilename) - { - return new MonoSymbolFile(mdbFilename); - } - public SourceFileEntry GetSourceFile(int index) - { - if (index < 1 || index > this.ot.SourceCount) - { - throw new ArgumentException(); - } - if (this.reader == null) - { - throw new InvalidOperationException(); - } - SourceFileEntry result; - - SourceFileEntry source; - if (this.source_file_hash.TryGetValue(index, out source)) - { - result = source; - } - else - { - long old_pos = this.reader.BaseStream.Position; - this.reader.BaseStream.Position = (long)(this.ot.SourceTableOffset + SourceFileEntry.Size * (index - 1)); - source = new SourceFileEntry(this, this.reader); - this.source_file_hash.Add(index, source); - this.reader.BaseStream.Position = old_pos; - result = source; - } - - return result; - } - public CompileUnitEntry GetCompileUnit(int index) - { - if (index < 1 || index > this.ot.CompileUnitCount) - { - throw new ArgumentException(); - } - if (this.reader == null) - { - throw new InvalidOperationException(); - } - CompileUnitEntry result; - CompileUnitEntry unit; - if (this.compile_unit_hash.TryGetValue(index, out unit)) - { - result = unit; - } - else - { - long old_pos = this.reader.BaseStream.Position; - this.reader.BaseStream.Position = (long)(this.ot.CompileUnitTableOffset + CompileUnitEntry.Size * (index - 1)); - unit = new CompileUnitEntry(this, this.reader); - this.compile_unit_hash.Add(index, unit); - this.reader.BaseStream.Position = old_pos; - result = unit; - } - return result; - } - private void read_methods() - { - if (this.method_token_hash == null) - { - this.method_token_hash = new Dictionary(); - this.method_list = new List(); - long old_pos = this.reader.BaseStream.Position; - this.reader.BaseStream.Position = (long)this.ot.MethodTableOffset; - for (int i = 0; i < this.MethodCount; i++) - { - MethodEntry entry = new MethodEntry(this, this.reader, i + 1); - this.method_token_hash.Add(entry.Token, entry); - this.method_list.Add(entry); - } - this.reader.BaseStream.Position = old_pos; - } - } - public MethodEntry GetMethodByToken(int token) - { - if (this.reader == null) - { - throw new InvalidOperationException(); - } - MethodEntry result; - this.read_methods(); - MethodEntry me; - this.method_token_hash.TryGetValue(token, out me); - result = me; - return result; - } - public MethodEntry GetMethod(int index) - { - if (index < 1 || index > this.ot.MethodCount) - { - throw new ArgumentException(); - } - if (this.reader == null) - { - throw new InvalidOperationException(); - } - MethodEntry result; - this.read_methods(); - result = this.method_list[index - 1]; - return result; - } - public int FindSource(string file_name) - { - if (this.reader == null) - { - throw new InvalidOperationException(); - } - int result; - if (this.source_name_hash == null) - { - this.source_name_hash = new Dictionary(); - for (int i = 0; i < this.ot.SourceCount; i++) - { - SourceFileEntry source = this.GetSourceFile(i + 1); - this.source_name_hash.Add(source.FileName, i); - } - } - int value; - if (!this.source_name_hash.TryGetValue(file_name, out value)) - { - result = -1; - } - else - { - result = value; - } - return result; - } - public AnonymousScopeEntry GetAnonymousScope(int id) - { - if (this.reader == null) - { - throw new InvalidOperationException(); - } - AnonymousScopeEntry result; - if (this.anonymous_scopes != null) - { - AnonymousScopeEntry scope; - this.anonymous_scopes.TryGetValue(id, out scope); - result = scope; - } - else - { - this.anonymous_scopes = new Dictionary(); - this.reader.BaseStream.Position = (long)this.ot.AnonymousScopeTableOffset; - for (int i = 0; i < this.ot.AnonymousScopeCount; i++) - { - AnonymousScopeEntry scope = new AnonymousScopeEntry(this.reader); - this.anonymous_scopes.Add(scope.ID, scope); - } - result = this.anonymous_scopes[id]; - } - - return result; - } - public void Dispose() - { - this.Dispose(true); - } - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (this.reader != null) - { - this.reader.Close(); - this.reader = null; - } - } - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFileException.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFileException.cs deleted file mode 100644 index f3750ab4..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFileException.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -namespace Mono.CompilerServices.SymbolWriter -{ - public class MonoSymbolFileException : Exception - { - public MonoSymbolFileException() - { - } - public MonoSymbolFileException(string message, params object[] args) : base(string.Format(message, args)) - { - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs deleted file mode 100644 index a8b38380..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs +++ /dev/null @@ -1,182 +0,0 @@ -//using System; -//using System.Collections.Generic; -//using System.IO; -//namespace Mono.CompilerServices.SymbolWriter -//{ -// public class MonoSymbolWriter -// { -// private List methods; -// private List sources; -// private List comp_units; -// protected readonly MonoSymbolFile file; -// private string filename; -// private SourceMethodBuilder current_method; -// private Stack current_method_stack = new Stack(); -// public MonoSymbolFile SymbolFile -// { -// get -// { -// return this.file; -// } -// } -// public MonoSymbolWriter(string filename) -// { -// this.methods = new List(); -// this.sources = new List(); -// this.comp_units = new List(); -// this.file = new MonoSymbolFile(); -// this.filename = filename + ".mdb"; -// } -// public void CloseNamespace() -// { -// } -// public void DefineLocalVariable(int index, string name) -// { -// if (this.current_method != null) -// { -// this.current_method.AddLocal(index, name); -// } -// } -// public void DefineCapturedLocal(int scope_id, string name, string captured_name) -// { -// this.file.DefineCapturedVariable(scope_id, name, captured_name, CapturedVariable.CapturedKind.Local); -// } -// public void DefineCapturedParameter(int scope_id, string name, string captured_name) -// { -// this.file.DefineCapturedVariable(scope_id, name, captured_name, CapturedVariable.CapturedKind.Parameter); -// } -// public void DefineCapturedThis(int scope_id, string captured_name) -// { -// this.file.DefineCapturedVariable(scope_id, "this", captured_name, CapturedVariable.CapturedKind.This); -// } -// public void DefineCapturedScope(int scope_id, int id, string captured_name) -// { -// this.file.DefineCapturedScope(scope_id, id, captured_name); -// } -// public void DefineScopeVariable(int scope, int index) -// { -// if (this.current_method != null) -// { -// this.current_method.AddScopeVariable(scope, index); -// } -// } -// public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, bool is_hidden) -// { -// if (this.current_method != null) -// { -// this.current_method.MarkSequencePoint(offset, file, line, column, is_hidden); -// } -// } -// public SourceMethodBuilder OpenMethod(ICompileUnit file, int ns_id, IMethodDef method) -// { -// SourceMethodBuilder builder = new SourceMethodBuilder(file, ns_id, method); -// this.current_method_stack.Push(this.current_method); -// this.current_method = builder; -// this.methods.Add(this.current_method); -// return builder; -// } -// public void CloseMethod() -// { -// this.current_method = this.current_method_stack.Pop(); -// } -// public SourceFileEntry DefineDocument(string url) -// { -// SourceFileEntry entry = new SourceFileEntry(this.file, url); -// this.sources.Add(entry); -// return entry; -// } -// public SourceFileEntry DefineDocument(string url, byte[] guid, byte[] checksum) -// { -// SourceFileEntry entry = new SourceFileEntry(this.file, url, guid, checksum); -// this.sources.Add(entry); -// return entry; -// } -// public CompileUnitEntry DefineCompilationUnit(SourceFileEntry source) -// { -// CompileUnitEntry entry = new CompileUnitEntry(this.file, source); -// this.comp_units.Add(entry); -// return entry; -// } -// public int DefineNamespace(string name, CompileUnitEntry unit, string[] using_clauses, int parent) -// { -// if (unit == null || using_clauses == null) -// { -// throw new NullReferenceException(); -// } -// return unit.DefineNamespace(name, using_clauses, parent); -// } -// public int OpenScope(int start_offset) -// { -// int result; -// if (this.current_method == null) -// { -// result = 0; -// } -// else -// { -// this.current_method.StartBlock(CodeBlockEntry.Type.Lexical, start_offset); -// result = 0; -// } -// return result; -// } -// public void CloseScope(int end_offset) -// { -// if (this.current_method != null) -// { -// this.current_method.EndBlock(end_offset); -// } -// } -// public void OpenCompilerGeneratedBlock(int start_offset) -// { -// if (this.current_method != null) -// { -// this.current_method.StartBlock(CodeBlockEntry.Type.CompilerGenerated, start_offset); -// } -// } -// public void CloseCompilerGeneratedBlock(int end_offset) -// { -// if (this.current_method != null) -// { -// this.current_method.EndBlock(end_offset); -// } -// } -// public void StartIteratorBody(int start_offset) -// { -// this.current_method.StartBlock(CodeBlockEntry.Type.IteratorBody, start_offset); -// } -// public void EndIteratorBody(int end_offset) -// { -// this.current_method.EndBlock(end_offset); -// } -// public void StartIteratorDispatcher(int start_offset) -// { -// this.current_method.StartBlock(CodeBlockEntry.Type.IteratorDispatcher, start_offset); -// } -// public void EndIteratorDispatcher(int end_offset) -// { -// this.current_method.EndBlock(end_offset); -// } -// public void DefineAnonymousScope(int id) -// { -// this.file.DefineAnonymousScope(id); -// } -// public void WriteSymbolFile(Guid guid) -// { -// foreach (SourceMethodBuilder method in this.methods) -// { -// method.DefineMethod(this.file); -// } -// try -// { -// File.Delete(this.filename); -// } -// catch -// { -// } -// using (FileStream fs = new FileStream(this.filename, FileMode.Create, FileAccess.Write)) -// { -// this.file.CreateSymbolFile(guid, fs); -// } -// } -// } -//} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryReader.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryReader.cs deleted file mode 100644 index 6715419c..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryReader.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.IO; -namespace Mono.CompilerServices.SymbolWriter -{ - internal class MyBinaryReader : BinaryReader - { - public MyBinaryReader(Stream stream) : base(stream) - { - } - public int ReadLeb128() - { - return base.Read7BitEncodedInt(); - } - public string ReadString(int offset) - { - long old_pos = this.BaseStream.Position; - this.BaseStream.Position = (long)offset; - string text = this.ReadString(); - this.BaseStream.Position = old_pos; - return text; - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryWriter.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryWriter.cs deleted file mode 100644 index c837da81..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryWriter.cs +++ /dev/null @@ -1,15 +0,0 @@ -//using System; -//using System.IO; -//namespace Mono.CompilerServices.SymbolWriter -//{ -// internal class MyBinaryWriter : BinaryWriter -// { -// public MyBinaryWriter(Stream stream) : base(stream) -// { -// } -// public void WriteLeb128(int value) -// { -// base.Write7BitEncodedInt(value); -// } -// } -//} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceEntry.cs deleted file mode 100644 index c2513c66..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceEntry.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -namespace Mono.CompilerServices.SymbolWriter -{ - public struct NamespaceEntry - { - public readonly string Name; - public readonly int Index; - public readonly int Parent; - public readonly string[] UsingClauses; - public NamespaceEntry(string name, int index, string[] using_clauses, int parent) - { - this.Name = name; - this.Index = index; - this.Parent = parent; - this.UsingClauses = ((using_clauses != null) ? using_clauses : new string[0]); - } - internal NamespaceEntry(MonoSymbolFile file, MyBinaryReader reader) - { - this.Name = reader.ReadString(); - this.Index = reader.ReadLeb128(); - this.Parent = reader.ReadLeb128(); - int count = reader.ReadLeb128(); - this.UsingClauses = new string[count]; - for (int i = 0; i < count; i++) - { - this.UsingClauses[i] = reader.ReadString(); - } - } - //internal void Write(MonoSymbolFile file, MyBinaryWriter bw) - //{ - // bw.Write(this.Name); - // bw.WriteLeb128(this.Index); - // bw.WriteLeb128(this.Parent); - // bw.WriteLeb128(this.UsingClauses.Length); - // string[] usingClauses = this.UsingClauses; - // for (int i = 0; i < usingClauses.Length; i++) - // { - // string uc = usingClauses[i]; - // bw.Write(uc); - // } - //} - public override string ToString() - { - return string.Format("[Namespace {0}:{1}:{2}]", this.Name, this.Index, this.Parent); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceInfo.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceInfo.cs deleted file mode 100644 index 13fca6d2..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceInfo.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections; -namespace Mono.CompilerServices.SymbolWriter -{ - internal class NamespaceInfo - { - public string Name; - public int NamespaceID; - public ArrayList UsingClauses = new ArrayList(); - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/OffsetTable.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/OffsetTable.cs deleted file mode 100644 index 27e86298..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/OffsetTable.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.IO; -namespace Mono.CompilerServices.SymbolWriter -{ - public class OffsetTable - { - [Flags] - public enum Flags - { - IsAspxSource = 1, - WindowsFileNames = 2 - } - public const int MajorVersion = 50; - public const int MinorVersion = 0; - public const long Magic = 5037318119232611860L; - public int TotalFileSize; - public int DataSectionOffset; - public int DataSectionSize; - public int CompileUnitCount; - public int CompileUnitTableOffset; - public int CompileUnitTableSize; - public int SourceCount; - public int SourceTableOffset; - public int SourceTableSize; - public int MethodCount; - public int MethodTableOffset; - public int MethodTableSize; - public int TypeCount; - public int AnonymousScopeCount; - public int AnonymousScopeTableOffset; - public int AnonymousScopeTableSize; - public OffsetTable.Flags FileFlags; - public int LineNumberTable_LineBase = -1; - public int LineNumberTable_LineRange = 8; - public int LineNumberTable_OpcodeBase = 9; - internal OffsetTable() - { - int platform = (int)Environment.OSVersion.Platform; - if (platform != 4 && platform != 128) - { - this.FileFlags |= OffsetTable.Flags.WindowsFileNames; - } - } - internal OffsetTable(BinaryReader reader, int major_version, int minor_version) - { - this.TotalFileSize = reader.ReadInt32(); - this.DataSectionOffset = reader.ReadInt32(); - this.DataSectionSize = reader.ReadInt32(); - this.CompileUnitCount = reader.ReadInt32(); - this.CompileUnitTableOffset = reader.ReadInt32(); - this.CompileUnitTableSize = reader.ReadInt32(); - this.SourceCount = reader.ReadInt32(); - this.SourceTableOffset = reader.ReadInt32(); - this.SourceTableSize = reader.ReadInt32(); - this.MethodCount = reader.ReadInt32(); - this.MethodTableOffset = reader.ReadInt32(); - this.MethodTableSize = reader.ReadInt32(); - this.TypeCount = reader.ReadInt32(); - this.AnonymousScopeCount = reader.ReadInt32(); - this.AnonymousScopeTableOffset = reader.ReadInt32(); - this.AnonymousScopeTableSize = reader.ReadInt32(); - this.LineNumberTable_LineBase = reader.ReadInt32(); - this.LineNumberTable_LineRange = reader.ReadInt32(); - this.LineNumberTable_OpcodeBase = reader.ReadInt32(); - this.FileFlags = (OffsetTable.Flags)reader.ReadInt32(); - } - internal void Write(BinaryWriter bw, int major_version, int minor_version) - { - bw.Write(this.TotalFileSize); - bw.Write(this.DataSectionOffset); - bw.Write(this.DataSectionSize); - bw.Write(this.CompileUnitCount); - bw.Write(this.CompileUnitTableOffset); - bw.Write(this.CompileUnitTableSize); - bw.Write(this.SourceCount); - bw.Write(this.SourceTableOffset); - bw.Write(this.SourceTableSize); - bw.Write(this.MethodCount); - bw.Write(this.MethodTableOffset); - bw.Write(this.MethodTableSize); - bw.Write(this.TypeCount); - bw.Write(this.AnonymousScopeCount); - bw.Write(this.AnonymousScopeTableOffset); - bw.Write(this.AnonymousScopeTableSize); - bw.Write(this.LineNumberTable_LineBase); - bw.Write(this.LineNumberTable_LineRange); - bw.Write(this.LineNumberTable_OpcodeBase); - bw.Write((int)this.FileFlags); - } - public override string ToString() - { - return string.Format("OffsetTable [{0} - {1}:{2} - {3}:{4}:{5} - {6}:{7}:{8} - {9}]", new object[] - { - this.TotalFileSize, - this.DataSectionOffset, - this.DataSectionSize, - this.SourceCount, - this.SourceTableOffset, - this.SourceTableSize, - this.MethodCount, - this.MethodTableOffset, - this.MethodTableSize, - this.TypeCount - }); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ScopeVariable.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ScopeVariable.cs deleted file mode 100644 index e3eedb1a..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ScopeVariable.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -namespace Mono.CompilerServices.SymbolWriter -{ - public struct ScopeVariable - { - public readonly int Scope; - public readonly int Index; - public ScopeVariable(int scope, int index) - { - this.Scope = scope; - this.Index = index; - } - internal ScopeVariable(MyBinaryReader reader) - { - this.Scope = reader.ReadLeb128(); - this.Index = reader.ReadLeb128(); - } - //internal void Write(MyBinaryWriter bw) - //{ - // bw.WriteLeb128(this.Scope); - // bw.WriteLeb128(this.Index); - //} - public override string ToString() - { - return string.Format("[ScopeVariable {0}:{1}]", this.Scope, this.Index); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceFileEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceFileEntry.cs deleted file mode 100644 index ab45bf5b..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceFileEntry.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.IO; -using System.Security.Cryptography; -namespace Mono.CompilerServices.SymbolWriter -{ - public class SourceFileEntry - { - public readonly int Index; - private int DataOffset; - private MonoSymbolFile file; - private string file_name; - private byte[] guid; - private byte[] hash; - private bool creating; - private bool auto_generated; - public static int Size - { - get - { - return 8; - } - } - public string FileName - { - get - { - return this.file_name; - } - } - public bool AutoGenerated - { - get - { - return this.auto_generated; - } - } - public SourceFileEntry(MonoSymbolFile file, string file_name) - { - this.file = file; - this.file_name = file_name; - this.Index = file.AddSource(this); - this.creating = true; - } - public SourceFileEntry(MonoSymbolFile file, string file_name, byte[] guid, byte[] checksum) : this(file, file_name) - { - this.guid = guid; - this.hash = checksum; - } - //internal void WriteData(MyBinaryWriter bw) - //{ - // this.DataOffset = (int)bw.BaseStream.Position; - // bw.Write(this.file_name); - // if (this.guid == null) - // { - // this.guid = Guid.NewGuid().ToByteArray(); - // try - // { - // using (FileStream fs = new FileStream(this.file_name, FileMode.Open, FileAccess.Read)) - // { - // MD5 md5 = MD5.Create(); - // this.hash = md5.ComputeHash(fs); - // } - // } - // catch - // { - // this.hash = new byte[16]; - // } - // } - // bw.Write(this.guid); - // bw.Write(this.hash); - // bw.Write(this.auto_generated ? 1 : 0); - //} - //internal void Write(BinaryWriter bw) - //{ - // bw.Write(this.Index); - // bw.Write(this.DataOffset); - //} - internal SourceFileEntry(MonoSymbolFile file, MyBinaryReader reader) - { - this.file = file; - this.Index = reader.ReadInt32(); - this.DataOffset = reader.ReadInt32(); - int old_pos = (int)reader.BaseStream.Position; - reader.BaseStream.Position = (long)this.DataOffset; - this.file_name = reader.ReadString(); - this.guid = reader.ReadBytes(16); - this.hash = reader.ReadBytes(16); - this.auto_generated = (reader.ReadByte() == 1); - reader.BaseStream.Position = (long)old_pos; - } - public void SetAutoGenerated() - { - if (!this.creating) - { - throw new InvalidOperationException(); - } - this.auto_generated = true; - this.file.OffsetTable.FileFlags |= OffsetTable.Flags.IsAspxSource; - } - public bool CheckChecksum() - { - bool result; - try - { - using (FileStream fs = new FileStream(this.file_name, FileMode.Open)) - { - MD5 md5 = MD5.Create(); - byte[] data = md5.ComputeHash(fs); - for (int i = 0; i < 16; i++) - { - if (data[i] != this.hash[i]) - { - result = false; - return result; - } - } - result = true; - } - } - catch - { - result = false; - } - return result; - } - public override string ToString() - { - return string.Format("SourceFileEntry ({0}:{1})", this.Index, this.DataOffset); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs deleted file mode 100644 index 8a8a0dff..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System; -using System.Collections.Generic; -namespace Mono.CompilerServices.SymbolWriter -{ - public class SourceMethodBuilder - { - private List _locals; - private List _blocks; - private List _scope_vars; - private Stack _block_stack; - private string _real_name; - private IMethodDef _method; - private ICompileUnit _comp_unit; - private int _ns_id; - private LineNumberEntry[] method_lines; - private int method_lines_pos = 0; - public CodeBlockEntry[] Blocks - { - get - { - CodeBlockEntry[] result; - if (this._blocks == null) - { - result = new CodeBlockEntry[0]; - } - else - { - CodeBlockEntry[] retval = new CodeBlockEntry[this._blocks.Count]; - this._blocks.CopyTo(retval, 0); - result = retval; - } - return result; - } - } - public CodeBlockEntry CurrentBlock - { - get - { - CodeBlockEntry result; - if (this._block_stack != null && this._block_stack.Count > 0) - { - result = this._block_stack.Peek(); - } - else - { - result = null; - } - return result; - } - } - public LocalVariableEntry[] Locals - { - get - { - LocalVariableEntry[] result; - if (this._locals == null) - { - result = new LocalVariableEntry[0]; - } - else - { - LocalVariableEntry[] retval = new LocalVariableEntry[this._locals.Count]; - this._locals.CopyTo(retval, 0); - result = retval; - } - return result; - } - } - public ScopeVariable[] ScopeVariables - { - get - { - ScopeVariable[] result; - if (this._scope_vars == null) - { - result = new ScopeVariable[0]; - } - else - { - ScopeVariable[] retval = new ScopeVariable[this._scope_vars.Count]; - this._scope_vars.CopyTo(retval); - result = retval; - } - return result; - } - } - public string RealMethodName - { - get - { - return this._real_name; - } - } - public ICompileUnit SourceFile - { - get - { - return this._comp_unit; - } - } - public IMethodDef Method - { - get - { - return this._method; - } - } - public SourceMethodBuilder(ICompileUnit comp_unit, int ns_id, IMethodDef method) - { - this._comp_unit = comp_unit; - this._method = method; - this._ns_id = ns_id; - this.method_lines = new LineNumberEntry[32]; - } - public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, bool is_hidden) - { - if (this.method_lines_pos == this.method_lines.Length) - { - LineNumberEntry[] tmp = this.method_lines; - this.method_lines = new LineNumberEntry[this.method_lines.Length * 2]; - Array.Copy(tmp, this.method_lines, this.method_lines_pos); - } - int file_idx = (file != null) ? file.Index : 0; - this.method_lines[this.method_lines_pos++] = new LineNumberEntry(file_idx, line, offset, is_hidden); - } - public void StartBlock(CodeBlockEntry.Type type, int start_offset) - { - if (this._block_stack == null) - { - this._block_stack = new Stack(); - } - if (this._blocks == null) - { - this._blocks = new List(); - } - int parent = (this.CurrentBlock != null) ? this.CurrentBlock.Index : -1; - CodeBlockEntry block = new CodeBlockEntry(this._blocks.Count + 1, parent, type, start_offset); - this._block_stack.Push(block); - this._blocks.Add(block); - } - public void EndBlock(int end_offset) - { - CodeBlockEntry block = this._block_stack.Pop(); - block.Close(end_offset); - } - public void AddLocal(int index, string name) - { - if (this._locals == null) - { - this._locals = new List(); - } - int block_idx = (this.CurrentBlock != null) ? this.CurrentBlock.Index : 0; - this._locals.Add(new LocalVariableEntry(index, name, block_idx)); - } - public void AddScopeVariable(int scope, int index) - { - if (this._scope_vars == null) - { - this._scope_vars = new List(); - } - this._scope_vars.Add(new ScopeVariable(scope, index)); - } - public void SetRealMethodName(string name) - { - this._real_name = name; - } - public void DefineMethod(MonoSymbolFile file) - { - LineNumberEntry[] lines = new LineNumberEntry[this.method_lines_pos]; - Array.Copy(this.method_lines, lines, this.method_lines_pos); - MethodEntry entry = new MethodEntry(file, this._comp_unit.Entry, this._method.Token, this.ScopeVariables, this.Locals, lines, this.Blocks, this.RealMethodName, (MethodEntry.Flags)0, this._ns_id); - file.AddMethod(entry); - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodImpl.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodImpl.cs deleted file mode 100644 index cdfc8667..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodImpl.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -namespace Mono.CompilerServices.SymbolWriter -{ - internal class SourceMethodImpl : IMethodDef - { - private string name; - private int token; - private int namespaceID; - public string Name - { - get - { - return this.name; - } - } - public int NamespaceID - { - get - { - return this.namespaceID; - } - } - public int Token - { - get - { - return this.token; - } - } - public SourceMethodImpl(string name, int token, int namespaceID) - { - this.name = name; - this.token = token; - this.namespaceID = namespaceID; - } - } -} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolDocumentWriterImpl.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolDocumentWriterImpl.cs deleted file mode 100644 index 1c22cb89..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolDocumentWriterImpl.cs +++ /dev/null @@ -1,33 +0,0 @@ -//using System; -//using System.Diagnostics.SymbolStore; -//namespace Mono.CompilerServices.SymbolWriter -//{ -// internal class SymbolDocumentWriterImpl : ISymbolDocumentWriter, ISourceFile, ICompileUnit -// { -// private CompileUnitEntry comp_unit; -// SourceFileEntry ISourceFile.Entry -// { -// get -// { -// return this.comp_unit.SourceFile; -// } -// } -// public CompileUnitEntry Entry -// { -// get -// { -// return this.comp_unit; -// } -// } -// public SymbolDocumentWriterImpl(CompileUnitEntry comp_unit) -// { -// this.comp_unit = comp_unit; -// } -// public void SetCheckSum(Guid algorithmId, byte[] checkSum) -// { -// } -// public void SetSource(byte[] source) -// { -// } -// } -//} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs deleted file mode 100644 index d489c4cb..00000000 --- a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs +++ /dev/null @@ -1,162 +0,0 @@ -//using System; -//using System.Collections; -//using System.Diagnostics.SymbolStore; -//using System.Reflection; -//using System.Text; -//namespace Mono.CompilerServices.SymbolWriter -//{ -// public class SymbolWriterImpl : ISymbolWriter -// { -// private MonoSymbolWriter msw; -// private int nextLocalIndex; -// private int currentToken; -// private string methodName; -// private Stack namespaceStack = new Stack(); -// private bool methodOpened; -// private Hashtable documents = new Hashtable(); -// private Guid guid; -// public SymbolWriterImpl(Guid guid) -// { -// this.guid = guid; -// } -// public void Close() -// { -// this.msw.WriteSymbolFile(this.guid); -// } -// public void CloseMethod() -// { -// if (this.methodOpened) -// { -// this.methodOpened = false; -// this.nextLocalIndex = 0; -// this.msw.CloseMethod(); -// } -// } -// public void CloseNamespace() -// { -// this.namespaceStack.Pop(); -// this.msw.CloseNamespace(); -// } -// public void CloseScope(int endOffset) -// { -// this.msw.CloseScope(endOffset); -// } -// public ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) -// { -// SymbolDocumentWriterImpl doc = (SymbolDocumentWriterImpl)this.documents[url]; -// if (doc == null) -// { -// SourceFileEntry entry = this.msw.DefineDocument(url); -// CompileUnitEntry comp_unit = this.msw.DefineCompilationUnit(entry); -// doc = new SymbolDocumentWriterImpl(comp_unit); -// this.documents[url] = doc; -// } -// return doc; -// } -// public void DefineField(SymbolToken parent, string name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) -// { -// } -// public void DefineGlobalVariable(string name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) -// { -// } -// public void DefineLocalVariable(string name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset) -// { -// this.msw.DefineLocalVariable(this.nextLocalIndex++, name); -// } -// public void DefineParameter(string name, ParameterAttributes attributes, int sequence, SymAddressKind addrKind, int addr1, int addr2, int addr3) -// { -// } -// public void DefineSequencePoints(ISymbolDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) -// { -// SymbolDocumentWriterImpl doc = (SymbolDocumentWriterImpl)document; -// SourceFileEntry file = (doc != null) ? doc.Entry.SourceFile : null; -// for (int i = 0; i < offsets.Length; i++) -// { -// if (i <= 0 || offsets[i] != offsets[i - 1] || lines[i] != lines[i - 1] || columns[i] != columns[i - 1]) -// { -// this.msw.MarkSequencePoint(offsets[i], file, lines[i], columns[i], false); -// } -// } -// } -// public void Initialize(IntPtr emitter, string filename, bool fFullBuild) -// { -// this.msw = new MonoSymbolWriter(filename); -// } -// public void OpenMethod(SymbolToken method) -// { -// this.currentToken = method.GetToken(); -// } -// public void OpenNamespace(string name) -// { -// NamespaceInfo i = new NamespaceInfo(); -// i.NamespaceID = -1; -// i.Name = name; -// this.namespaceStack.Push(i); -// } -// public int OpenScope(int startOffset) -// { -// return this.msw.OpenScope(startOffset); -// } -// public void SetMethodSourceRange(ISymbolDocumentWriter startDoc, int startLine, int startColumn, ISymbolDocumentWriter endDoc, int endLine, int endColumn) -// { -// int nsId = this.GetCurrentNamespace(startDoc); -// SourceMethodImpl sm = new SourceMethodImpl(this.methodName, this.currentToken, nsId); -// this.msw.OpenMethod(((ICompileUnit)startDoc).Entry, nsId, sm); -// this.methodOpened = true; -// } -// public void SetScopeRange(int scopeID, int startOffset, int endOffset) -// { -// } -// public void SetSymAttribute(SymbolToken parent, string name, byte[] data) -// { -// if (name == "__name") -// { -// this.methodName = Encoding.UTF8.GetString(data); -// } -// } -// public void SetUnderlyingWriter(IntPtr underlyingWriter) -// { -// } -// public void SetUserEntryPoint(SymbolToken entryMethod) -// { -// } -// public void UsingNamespace(string fullName) -// { -// if (this.namespaceStack.Count == 0) -// { -// this.OpenNamespace(""); -// } -// NamespaceInfo ni = (NamespaceInfo)this.namespaceStack.Peek(); -// if (ni.NamespaceID != -1) -// { -// NamespaceInfo old = ni; -// this.CloseNamespace(); -// this.OpenNamespace(old.Name); -// ni = (NamespaceInfo)this.namespaceStack.Peek(); -// ni.UsingClauses = old.UsingClauses; -// } -// ni.UsingClauses.Add(fullName); -// } -// private int GetCurrentNamespace(ISymbolDocumentWriter doc) -// { -// if (this.namespaceStack.Count == 0) -// { -// this.OpenNamespace(""); -// } -// NamespaceInfo ni = (NamespaceInfo)this.namespaceStack.Peek(); -// if (ni.NamespaceID == -1) -// { -// string[] usings = (string[])ni.UsingClauses.ToArray(typeof(string)); -// int parentId = 0; -// if (this.namespaceStack.Count > 1) -// { -// this.namespaceStack.Pop(); -// parentId = ((NamespaceInfo)this.namespaceStack.Peek()).NamespaceID; -// this.namespaceStack.Push(ni); -// } -// ni.NamespaceID = this.msw.DefineNamespace(ni.Name, ((ICompileUnit)doc).Entry, usings, parentId); -// } -// return ni.NamespaceID; -// } -// } -//} diff --git a/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/.editorconfig b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/.editorconfig new file mode 100644 index 00000000..d1a80c6d --- /dev/null +++ b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/.editorconfig @@ -0,0 +1,3 @@ +[*.cs] +indent_style = space +indent_size = 2 diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitAccess.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitAccess.cs similarity index 97% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitAccess.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitAccess.cs index e8e77b0b..d92a5b74 100644 --- a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitAccess.cs +++ b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitAccess.cs @@ -189,6 +189,12 @@ internal void ReadBString(out string value) { offset += len; } + internal string ReadBString(int len) { + var result = Encoding.UTF8.GetString(buffer, offset, len); + offset += len; + return result; + } + internal void ReadCString(out string value) { int len = 0; while (offset + len < buffer.Length && buffer[offset + len] != 0) { diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitSet.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitSet.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitSet.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/BitSet.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/CvInfo.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/CvInfo.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/CvInfo.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/CvInfo.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DataStream.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DataStream.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DataStream.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DataStream.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiHeader.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiHeader.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiHeader.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiHeader.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiSecCon.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiSecCon.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiSecCon.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/DbiSecCon.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/IntHashTable.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/IntHashTable.cs similarity index 99% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/IntHashTable.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/IntHashTable.cs index 42489ad5..db0e41be 100644 --- a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/IntHashTable.cs +++ b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/IntHashTable.cs @@ -89,7 +89,7 @@ where n is the number of times we've hit a collided bucket and If this is true, then we are guaranteed to visit every bucket in exactly hashsize probes, since the least common multiple of hashsize - and h2(key) will be hashsize * h2(key). ( This is the first number + and h2(key) will be hashsize * h2(key). (This is the first number where adding h2 to h1 mod hashsize will be 0 and we will search the same bucket twice). @@ -118,7 +118,7 @@ you inserted. // Suppose our Hashtable currently has capacity x and enough elements are added // such that a resize needs to occur. Resizing first computes 2x then finds the // first prime in the table greater than 2x, i.e. if primes are ordered - // p_1, p_2, ? p_i,? it finds p_n such that p_n-1 < 2x < p_n. + // p_1, p_2, , p_i,, it finds p_n such that p_n-1 < 2x < p_n. // Doubling is important for preserving the asymptotic complexity of the // hashtable operations such as add. Having a prime guarantees that double // hashing does not lead to infinite loops. IE, your hash function will be diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/Interfaces.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/Interfaces.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/Interfaces.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/Interfaces.cs diff --git a/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/LICENSE b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/LICENSE new file mode 100644 index 00000000..7bfc997e --- /dev/null +++ b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/LICENSE @@ -0,0 +1,22 @@ +Microsoft Public License (Ms-PL) + +This license governs use of the accompanying software. If you use the software, you +accept this license. If you do not accept the license, do not use the software. + +1. Definitions +The terms "reproduce," "reproduction," "derivative works," and "distribution" have the +same meaning here as under U.S. copyright law. +A "contribution" is the original software, or any additions or changes to the software. +A "contributor" is any person that distributes its contribution under this license. +"Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights +(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. +(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations +(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. +(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. +(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. +(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. +(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/MsfDirectory.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/MsfDirectory.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/MsfDirectory.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/MsfDirectory.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbConstant.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbConstant.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbConstant.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbConstant.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbDebugException.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbDebugException.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbDebugException.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbDebugException.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbException.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbException.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbException.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbException.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFile.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFile.cs similarity index 74% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFile.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFile.cs index 9e560281..9435d6ef 100644 --- a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFile.cs +++ b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFile.cs @@ -9,10 +9,10 @@ // //----------------------------------------------------------------------------- using System; -using System.Collections; + using System.Collections.Generic; using System.IO; -using System.Diagnostics.SymbolStore; +using Mono.Cecil.Cil; namespace Microsoft.Cci.Pdb { internal class PdbFile { @@ -131,11 +131,11 @@ static IntHashTable LoadNameStream(BitAccess bits) { return ht; } - private static PdbFunction match = new PdbFunction(); - private static int FindFunction(PdbFunction[] funcs, ushort sec, uint off) { - match.segment = sec; - match.address = off; + var match = new PdbFunction { + segment = sec, + address = off, + }; return Array.BinarySearch(funcs, match, PdbFunction.byAddress); } @@ -148,52 +148,9 @@ static void LoadManagedLines(PdbFunction[] funcs, PdbReader reader, uint limit) { Array.Sort(funcs, PdbFunction.byAddressAndToken); - IntHashTable checks = new IntHashTable(); - // Read the files first int begin = bits.Position; - while (bits.Position < limit) { - int sig; - int siz; - bits.ReadInt32(out sig); - bits.ReadInt32(out siz); - int place = bits.Position; - int endSym = bits.Position + siz; - - switch ((DEBUG_S_SUBSECTION)sig) { - case DEBUG_S_SUBSECTION.FILECHKSMS: - while (bits.Position < endSym) { - CV_FileCheckSum chk; - - int ni = bits.Position - place; - bits.ReadUInt32(out chk.name); - bits.ReadUInt8(out chk.len); - bits.ReadUInt8(out chk.type); - - string name = (string)names[(int)chk.name]; - int guidStream; - Guid doctypeGuid = SymDocumentType.Text; - Guid languageGuid = Guid.Empty; - Guid vendorGuid = Guid.Empty; - if (nameIndex.TryGetValue("/SRC/FILES/"+name.ToUpperInvariant(), out guidStream)) { - var guidBits = new BitAccess(0x100); - dir.streams[guidStream].Read(reader, guidBits); - LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid); - } - - PdbSource src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid); - checks.Add(ni, src); - bits.Position += chk.len; - bits.Align(4); - } - bits.Position = endSym; - break; - - default: - bits.Position = endSym; - break; - } - } + IntHashTable checks = ReadSourceFileInfo(bits, limit, names, dir, nameIndex, reader); // Read the lines next. bits.Position = begin; @@ -222,7 +179,7 @@ static void LoadManagedLines(PdbFunction[] funcs, func = f; funcIndex--; } - } else { + } else { while (funcIndex < funcs.Length-1 && func.lines != null) { var f = funcs[funcIndex+1]; if (f.segment != sec.sec || f.address != sec.off) break; @@ -297,7 +254,7 @@ static void LoadManagedLines(PdbFunction[] funcs, static void LoadFuncsFromDbiModule(BitAccess bits, DbiModuleInfo info, IntHashTable names, - ArrayList funcList, + List funcList, bool readStrings, MsfDirectory dir, Dictionary nameIndex, @@ -340,7 +297,7 @@ static void LoadDbiStream(BitAccess bits, //} // Read gpmod section. - ArrayList modList = new ArrayList(); + List modList = new List(); int end = bits.Position + dh.gpmodiSize; while (bits.Position < end) { DbiModuleInfo mod = new DbiModuleInfo(bits, readStrings); @@ -352,7 +309,7 @@ static void LoadDbiStream(BitAccess bits, } if (modList.Count > 0) { - modules = (DbiModuleInfo[])modList.ToArray(typeof(DbiModuleInfo)); + modules = modList.ToArray(); } else { modules = null; } @@ -380,12 +337,9 @@ static void LoadDbiStream(BitAccess bits, bits.Position = end; } - internal static PdbFunction[] LoadFunctions(Stream read, bool readAllStrings, out int age, out Guid guid) { + internal static PdbFunction[] LoadFunctions(Stream read, out Dictionary tokenToSourceMapping, out string sourceServerData, out int age, out Guid guid) { + tokenToSourceMapping = new Dictionary(); BitAccess bits = new BitAccess(512 * 1024); - return LoadFunctions(read, bits, readAllStrings, out age, out guid); - } - - internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool readAllStrings, out int age, out Guid guid) { PdbFileHeader head = new PdbFileHeader(read, bits); PdbReader reader = new PdbReader(read, head.pageSize); MsfDirectory dir = new MsfDirectory(reader, head, bits); @@ -398,26 +352,39 @@ internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool re if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { throw new PdbException("No `name' stream"); } - dir.streams[nameStream].Read(reader, bits); IntHashTable names = LoadNameStream(bits); + int srcsrvStream; + if (!nameIndex.TryGetValue("SRCSRV", out srcsrvStream)) + sourceServerData = string.Empty; + else { + DataStream dataStream = dir.streams[srcsrvStream]; + byte[] bytes = new byte[dataStream.contentSize]; + dataStream.Read(reader, bits); + sourceServerData = bits.ReadBString(bytes.Length); + } + dir.streams[3].Read(reader, bits); - LoadDbiStream(bits, out modules, out header, readAllStrings); + LoadDbiStream(bits, out modules, out header, true); - ArrayList funcList = new ArrayList(); + List funcList = new List(); if (modules != null) { for (int m = 0; m < modules.Length; m++) { - if (modules[m].stream > 0) { - dir.streams[modules[m].stream].Read(reader, bits); - LoadFuncsFromDbiModule(bits, modules[m], names, funcList, - readAllStrings, dir, nameIndex, reader); + var module = modules[m]; + if (module.stream > 0) { + dir.streams[module.stream].Read(reader, bits); + if (module.moduleName == "TokenSourceLineInfo") { + LoadTokenToSourceInfo(bits, module, names, dir, nameIndex, reader, tokenToSourceMapping); + continue; + } + LoadFuncsFromDbiModule(bits, module, names, funcList, true, dir, nameIndex, reader); } } } - PdbFunction[] funcs = (PdbFunction[])funcList.ToArray(typeof(PdbFunction)); + PdbFunction[] funcs = funcList.ToArray(); // After reading the functions, apply the token remapping table if it exists. if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) { @@ -435,5 +402,136 @@ internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool re //Array.Sort(funcs, PdbFunction.byToken); return funcs; } + + private static void LoadTokenToSourceInfo(BitAccess bits, DbiModuleInfo module, IntHashTable names, MsfDirectory dir, + Dictionary nameIndex, PdbReader reader, Dictionary tokenToSourceMapping) { + bits.Position = 0; + int sig; + bits.ReadInt32(out sig); + if (sig != 4) { + throw new PdbDebugException("Invalid signature. (sig={0})", sig); + } + + bits.Position = 4; + + while (bits.Position < module.cbSyms) { + ushort siz; + ushort rec; + + bits.ReadUInt16(out siz); + int star = bits.Position; + int stop = bits.Position + siz; + bits.Position = star; + bits.ReadUInt16(out rec); + + switch ((SYM)rec) { + case SYM.S_OEM: + OemSymbol oem; + + bits.ReadGuid(out oem.idOem); + bits.ReadUInt32(out oem.typind); + // internal byte[] rgl; // user data, force 4-byte alignment + + if (oem.idOem == PdbFunction.msilMetaData) { + string name = bits.ReadString(); + if (name == "TSLI") { + uint token; + uint file_id; + uint line; + uint column; + uint endLine; + uint endColumn; + bits.ReadUInt32(out token); + bits.ReadUInt32(out file_id); + bits.ReadUInt32(out line); + bits.ReadUInt32(out column); + bits.ReadUInt32(out endLine); + bits.ReadUInt32(out endColumn); + PdbTokenLine tokenLine; + if (!tokenToSourceMapping.TryGetValue(token, out tokenLine)) + tokenToSourceMapping.Add(token, new PdbTokenLine(token, file_id, line, column, endLine, endColumn)); + else { + while (tokenLine.nextLine != null) tokenLine = tokenLine.nextLine; + tokenLine.nextLine = new PdbTokenLine(token, file_id, line, column, endLine, endColumn); + } + } + bits.Position = stop; + break; + } else { + throw new PdbDebugException("OEM section: guid={0} ti={1}", + oem.idOem, oem.typind); + // bits.Position = stop; + } + + case SYM.S_END: + bits.Position = stop; + break; + + default: + //Console.WriteLine("{0,6}: {1:x2} {2}", + // bits.Position, rec, (SYM)rec); + bits.Position = stop; + break; + } + } + + bits.Position = module.cbSyms + module.cbOldLines; + int limit = module.cbSyms + module.cbOldLines + module.cbLines; + IntHashTable sourceFiles = ReadSourceFileInfo(bits, (uint)limit, names, dir, nameIndex, reader); + foreach (var tokenLine in tokenToSourceMapping.Values) { + tokenLine.sourceFile = (PdbSource)sourceFiles[(int)tokenLine.file_id]; + } + + } + + private static IntHashTable ReadSourceFileInfo(BitAccess bits, uint limit, IntHashTable names, MsfDirectory dir, + Dictionary nameIndex, PdbReader reader) { + IntHashTable checks = new IntHashTable(); + + int begin = bits.Position; + while (bits.Position < limit) { + int sig; + int siz; + bits.ReadInt32(out sig); + bits.ReadInt32(out siz); + int place = bits.Position; + int endSym = bits.Position + siz; + + switch ((DEBUG_S_SUBSECTION)sig) { + case DEBUG_S_SUBSECTION.FILECHKSMS: + while (bits.Position < endSym) { + CV_FileCheckSum chk; + + int ni = bits.Position - place; + bits.ReadUInt32(out chk.name); + bits.ReadUInt8(out chk.len); + bits.ReadUInt8(out chk.type); + + string name = (string)names[(int)chk.name]; + int guidStream; + Guid doctypeGuid = DocumentType.Text.ToGuid(); + Guid languageGuid = Guid.Empty; + Guid vendorGuid = Guid.Empty; + if (nameIndex.TryGetValue("/SRC/FILES/"+name.ToUpperInvariant(), out guidStream)) { + var guidBits = new BitAccess(0x100); + dir.streams[guidStream].Read(reader, guidBits); + LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid); + } + + PdbSource src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid); + checks.Add(ni, src); + bits.Position += chk.len; + bits.Align(4); + } + bits.Position = endSym; + break; + + default: + bits.Position = endSym; + break; + } + } + return checks; + } } } diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs similarity index 82% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs index e1f56dbe..0a920388 100644 --- a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs +++ b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs @@ -24,6 +24,8 @@ internal class PdbFileHeader { // this.pageSize = pageSize; //} + const string MAGIC = "Microsoft C/C++ MSF 7.00"; + internal PdbFileHeader(Stream reader, BitAccess bits) { bits.MinCapacity(56); reader.Seek(0, SeekOrigin.Begin); @@ -37,15 +39,18 @@ internal PdbFileHeader(Stream reader, BitAccess bits) { bits.ReadInt32(out this.directorySize); // 44..47 bits.ReadInt32(out this.zero); // 48..51 + if (Magic != MAGIC) { + throw new InvalidOperationException("Magic is wrong."); + } int directoryPages = ((((directorySize + pageSize - 1) / pageSize) * 4) + pageSize - 1) / pageSize; this.directoryRoot = new int[directoryPages]; bits.FillBuffer(reader, directoryPages * 4); bits.ReadInt32(this.directoryRoot); } - //internal string Magic { - // get { return StringFromBytesUTF8(magic); } - //} + string Magic { + get { return StringFromBytesUTF8(magic, 0, MAGIC.Length); } + } //internal void Write(Stream writer, BitAccess bits) { // bits.MinCapacity(pageSize); @@ -63,18 +68,18 @@ internal PdbFileHeader(Stream reader, BitAccess bits) { //////////////////////////////////////////////////// Helper Functions. // - //internal static string StringFromBytesUTF8(byte[] bytes) { - // return StringFromBytesUTF8(bytes, 0, bytes.Length); - //} + static string StringFromBytesUTF8(byte[] bytes) { + return StringFromBytesUTF8(bytes, 0, bytes.Length); + } - //internal static string StringFromBytesUTF8(byte[] bytes, int offset, int length) { - // for (int i = 0; i < length; i++) { - // if (bytes[offset + i] < ' ') { - // length = i; - // } - // } - // return Encoding.UTF8.GetString(bytes, offset, length); - //} + static string StringFromBytesUTF8(byte[] bytes, int offset, int length) { + for (int i = 0; i < length; i++) { + if (bytes[offset + i] < ' ') { + length = i; + } + } + return Encoding.UTF8.GetString(bytes, offset, length); + } ////////////////////////////////////////////////////////////// Fields. // diff --git a/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFunction.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFunction.cs new file mode 100644 index 00000000..b02b97fe --- /dev/null +++ b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbFunction.cs @@ -0,0 +1,498 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Cci.Pdb { + internal class PdbFunction { + static internal readonly Guid msilMetaData = new Guid(0xc6ea3fc9, 0x59b3, 0x49d6, 0xbc, 0x25, + 0x09, 0x02, 0xbb, 0xab, 0xb4, 0x60); + static internal readonly IComparer byAddress = new PdbFunctionsByAddress(); + static internal readonly IComparer byAddressAndToken = new PdbFunctionsByAddressAndToken(); + //static internal readonly IComparer byToken = new PdbFunctionsByToken(); + + internal uint token; + internal uint slotToken; + internal uint tokenOfMethodWhoseUsingInfoAppliesToThisMethod; + //internal string name; + //internal string module; + //internal ushort flags; + + internal uint segment; + internal uint address; + internal uint length; + + //internal byte[] metadata; + internal PdbScope[] scopes; + internal PdbSlot[] slots; + internal PdbConstant[] constants; + internal string[] usedNamespaces; + internal PdbLines[] lines; + internal ushort[]/*?*/ usingCounts; + internal IEnumerable/*?*/ namespaceScopes; + internal string/*?*/ iteratorClass; + internal List/*?*/ iteratorScopes; + internal PdbSynchronizationInformation/*?*/ synchronizationInformation; + + private static string StripNamespace(string module) { + int li = module.LastIndexOf('.'); + if (li > 0) { + return module.Substring(li + 1); + } + return module; + } + + + internal static PdbFunction[] LoadManagedFunctions(/*string module,*/ + BitAccess bits, uint limit, + bool readStrings) { + //string mod = StripNamespace(module); + int begin = bits.Position; + int count = 0; + + while (bits.Position < limit) { + ushort siz; + ushort rec; + + bits.ReadUInt16(out siz); + int star = bits.Position; + int stop = bits.Position + siz; + bits.Position = star; + bits.ReadUInt16(out rec); + + switch ((SYM)rec) { + case SYM.S_GMANPROC: + case SYM.S_LMANPROC: + ManProcSym proc; + bits.ReadUInt32(out proc.parent); + bits.ReadUInt32(out proc.end); + bits.Position = (int)proc.end; + count++; + break; + + case SYM.S_END: + bits.Position = stop; + break; + + default: + //Console.WriteLine("{0,6}: {1:x2} {2}", + // bits.Position, rec, (SYM)rec); + bits.Position = stop; + break; + } + } + if (count == 0) { + return null; + } + + bits.Position = begin; + PdbFunction[] funcs = new PdbFunction[count]; + int func = 0; + + while (bits.Position < limit) { + ushort siz; + ushort rec; + + bits.ReadUInt16(out siz); + int star = bits.Position; + int stop = bits.Position + siz; + bits.ReadUInt16(out rec); + + switch ((SYM)rec) { + + case SYM.S_GMANPROC: + case SYM.S_LMANPROC: + ManProcSym proc; + //int offset = bits.Position; + + bits.ReadUInt32(out proc.parent); + bits.ReadUInt32(out proc.end); + bits.ReadUInt32(out proc.next); + bits.ReadUInt32(out proc.len); + bits.ReadUInt32(out proc.dbgStart); + bits.ReadUInt32(out proc.dbgEnd); + bits.ReadUInt32(out proc.token); + bits.ReadUInt32(out proc.off); + bits.ReadUInt16(out proc.seg); + bits.ReadUInt8(out proc.flags); + bits.ReadUInt16(out proc.retReg); + if (readStrings) { + bits.ReadCString(out proc.name); + } else { + bits.SkipCString(out proc.name); + } + //Console.WriteLine("token={0:X8} [{1}::{2}]", proc.token, module, proc.name); + + bits.Position = stop; + funcs[func++] = new PdbFunction(/*module,*/ proc, bits); + break; + + default: { + //throw new PdbDebugException("Unknown SYMREC {0}", (SYM)rec); + bits.Position = stop; + break; + } + } + } + return funcs; + } + + internal static void CountScopesAndSlots(BitAccess bits, uint limit, + out int constants, out int scopes, out int slots, out int usedNamespaces) { + int pos = bits.Position; + BlockSym32 block; + constants = 0; + slots = 0; + scopes = 0; + usedNamespaces = 0; + + while (bits.Position < limit) { + ushort siz; + ushort rec; + + bits.ReadUInt16(out siz); + int star = bits.Position; + int stop = bits.Position + siz; + bits.Position = star; + bits.ReadUInt16(out rec); + + switch ((SYM)rec) { + case SYM.S_BLOCK32: { + bits.ReadUInt32(out block.parent); + bits.ReadUInt32(out block.end); + + scopes++; + bits.Position = (int)block.end; + break; + } + + case SYM.S_MANSLOT: + slots++; + bits.Position = stop; + break; + + case SYM.S_UNAMESPACE: + usedNamespaces++; + bits.Position = stop; + break; + + case SYM.S_MANCONSTANT: + constants++; + bits.Position = stop; + break; + + default: + bits.Position = stop; + break; + } + } + bits.Position = pos; + } + + internal PdbFunction() { + } + + internal PdbFunction(/*string module, */ManProcSym proc, BitAccess bits) { + this.token = proc.token; + //this.module = module; + //this.name = proc.name; + //this.flags = proc.flags; + this.segment = proc.seg; + this.address = proc.off; + this.length = proc.len; + + if (proc.seg != 1) { + throw new PdbDebugException("Segment is {0}, not 1.", proc.seg); + } + if (proc.parent != 0 || proc.next != 0) { + throw new PdbDebugException("Warning parent={0}, next={1}", + proc.parent, proc.next); + } + //if (proc.dbgStart != 0 || proc.dbgEnd != 0) { + // throw new PdbDebugException("Warning DBG start={0}, end={1}", + // proc.dbgStart, proc.dbgEnd); + //} + + int constantCount; + int scopeCount; + int slotCount; + int usedNamespacesCount; + CountScopesAndSlots(bits, proc.end, out constantCount, out scopeCount, out slotCount, out usedNamespacesCount); + int scope = constantCount > 0 || slotCount > 0 || usedNamespacesCount > 0 ? 1 : 0; + int slot = 0; + int constant = 0; + int usedNs = 0; + scopes = new PdbScope[scopeCount+scope]; + slots = new PdbSlot[slotCount]; + constants = new PdbConstant[constantCount]; + usedNamespaces = new string[usedNamespacesCount]; + + if (scope > 0) + scopes[0] = new PdbScope(this.address, proc.len, slots, constants, usedNamespaces); + + while (bits.Position < proc.end) { + ushort siz; + ushort rec; + + bits.ReadUInt16(out siz); + int star = bits.Position; + int stop = bits.Position + siz; + bits.Position = star; + bits.ReadUInt16(out rec); + + switch ((SYM)rec) { + case SYM.S_OEM: { // 0x0404 + OemSymbol oem; + + bits.ReadGuid(out oem.idOem); + bits.ReadUInt32(out oem.typind); + // internal byte[] rgl; // user data, force 4-byte alignment + + if (oem.idOem == msilMetaData) { + string name = bits.ReadString(); + if (name == "MD2") { + byte version; + bits.ReadUInt8(out version); + if (version == 4) { + byte count; + bits.ReadUInt8(out count); + bits.Align(4); + while (count-- > 0) + this.ReadCustomMetadata(bits); + } + } else if (name == "asyncMethodInfo") { + this.synchronizationInformation = new PdbSynchronizationInformation(bits); + } + bits.Position = stop; + break; + } else { + throw new PdbDebugException("OEM section: guid={0} ti={1}", + oem.idOem, oem.typind); + // bits.Position = stop; + } + } + + case SYM.S_BLOCK32: { + BlockSym32 block = new BlockSym32(); + + bits.ReadUInt32(out block.parent); + bits.ReadUInt32(out block.end); + bits.ReadUInt32(out block.len); + bits.ReadUInt32(out block.off); + bits.ReadUInt16(out block.seg); + bits.SkipCString(out block.name); + bits.Position = stop; + + scopes[scope++] = new PdbScope(this.address, block, bits, out slotToken); + bits.Position = (int)block.end; + break; + } + + case SYM.S_MANSLOT: + slots[slot++] = new PdbSlot(bits); + bits.Position = stop; + break; + + case SYM.S_MANCONSTANT: + constants[constant++] = new PdbConstant(bits); + bits.Position = stop; + break; + + case SYM.S_UNAMESPACE: + bits.ReadCString(out usedNamespaces[usedNs++]); + bits.Position = stop; + break; + + case SYM.S_END: + bits.Position = stop; + break; + + default: { + //throw new PdbDebugException("Unknown SYM: {0}", (SYM)rec); + bits.Position = stop; + break; + } + } + } + + if (bits.Position != proc.end) { + throw new PdbDebugException("Not at S_END"); + } + + ushort esiz; + ushort erec; + bits.ReadUInt16(out esiz); + bits.ReadUInt16(out erec); + + if (erec != (ushort)SYM.S_END) { + throw new PdbDebugException("Missing S_END"); + } + } + + private void ReadCustomMetadata(BitAccess bits) { + int savedPosition = bits.Position; + byte version; + bits.ReadUInt8(out version); + if (version != 4) { + throw new PdbDebugException("Unknown custom metadata item version: {0}", version); + } + byte kind; + bits.ReadUInt8(out kind); + bits.Align(4); + uint numberOfBytesInItem; + bits.ReadUInt32(out numberOfBytesInItem); + switch (kind) { + case 0: this.ReadUsingInfo(bits); break; + case 1: this.ReadForwardInfo(bits); break; + case 2: break; // this.ReadForwardedToModuleInfo(bits); break; + case 3: this.ReadIteratorLocals(bits); break; + case 4: this.ReadForwardIterator(bits); break; + // TODO: handle unknown custom metadata, 5 & 6 are new with roslyn, see https://roslyn.codeplex.com/workitem/54 + } + bits.Position = savedPosition+(int)numberOfBytesInItem; + } + + private void ReadForwardIterator(BitAccess bits) { + this.iteratorClass = bits.ReadString(); + } + + private void ReadIteratorLocals(BitAccess bits) { + uint numberOfLocals; + bits.ReadUInt32(out numberOfLocals); + this.iteratorScopes = new List((int)numberOfLocals); + while (numberOfLocals-- > 0) { + uint ilStartOffset; + uint ilEndOffset; + bits.ReadUInt32(out ilStartOffset); + bits.ReadUInt32(out ilEndOffset); + this.iteratorScopes.Add(new PdbIteratorScope(ilStartOffset, ilEndOffset-ilStartOffset)); + } + } + + //private void ReadForwardedToModuleInfo(BitAccess bits) { + //} + + private void ReadForwardInfo(BitAccess bits) { + bits.ReadUInt32(out this.tokenOfMethodWhoseUsingInfoAppliesToThisMethod); + } + + private void ReadUsingInfo(BitAccess bits) { + ushort numberOfNamespaces; + bits.ReadUInt16(out numberOfNamespaces); + this.usingCounts = new ushort[numberOfNamespaces]; + for (ushort i = 0; i < numberOfNamespaces; i++) { + bits.ReadUInt16(out this.usingCounts[i]); + } + } + + internal class PdbFunctionsByAddress : IComparer { + public int Compare(Object x, Object y) { + PdbFunction fx = (PdbFunction)x; + PdbFunction fy = (PdbFunction)y; + + if (fx.segment < fy.segment) { + return -1; + } else if (fx.segment > fy.segment) { + return 1; + } else if (fx.address < fy.address) { + return -1; + } else if (fx.address > fy.address) { + return 1; + } else { + return 0; + } + } + } + + internal class PdbFunctionsByAddressAndToken : IComparer { + public int Compare(Object x, Object y) { + PdbFunction fx = (PdbFunction)x; + PdbFunction fy = (PdbFunction)y; + + if (fx.segment < fy.segment) { + return -1; + } else if (fx.segment > fy.segment) { + return 1; + } else if (fx.address < fy.address) { + return -1; + } else if (fx.address > fy.address) { + return 1; + } else { + if (fx.token < fy.token) + return -1; + else if (fx.token > fy.token) + return 1; + else + return 0; + } + } + } + + //internal class PdbFunctionsByToken : IComparer { + // public int Compare(Object x, Object y) { + // PdbFunction fx = (PdbFunction)x; + // PdbFunction fy = (PdbFunction)y; + + // if (fx.token < fy.token) { + // return -1; + // } else if (fx.token > fy.token) { + // return 1; + // } else { + // return 0; + // } + // } + + //} + } + + internal class PdbSynchronizationInformation { + internal uint kickoffMethodToken; + internal uint generatedCatchHandlerIlOffset; + internal PdbSynchronizationPoint[] synchronizationPoints; + + internal PdbSynchronizationInformation(BitAccess bits) { + uint asyncStepInfoCount; + bits.ReadUInt32(out this.kickoffMethodToken); + bits.ReadUInt32(out this.generatedCatchHandlerIlOffset); + bits.ReadUInt32(out asyncStepInfoCount); + this.synchronizationPoints = new PdbSynchronizationPoint[asyncStepInfoCount]; + for (uint i = 0; i < asyncStepInfoCount; i += 1) { + this.synchronizationPoints[i] = new PdbSynchronizationPoint(bits); + } + } + + public uint GeneratedCatchHandlerOffset { + get { return this.generatedCatchHandlerIlOffset; } + } + } + + internal class PdbSynchronizationPoint { + internal uint synchronizeOffset; + internal uint continuationMethodToken; + internal uint continuationOffset; + + internal PdbSynchronizationPoint(BitAccess bits) { + bits.ReadUInt32(out this.synchronizeOffset); + bits.ReadUInt32(out this.continuationMethodToken); + bits.ReadUInt32(out this.continuationOffset); + } + + public uint SynchronizeOffset { + get { return this.synchronizeOffset; } + } + + public uint ContinuationOffset { + get { return this.continuationOffset; } + } + } + +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLine.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLine.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLine.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLine.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLines.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLines.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLines.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbLines.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbReader.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbReader.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbReader.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbReader.cs diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbScope.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbScope.cs similarity index 98% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbScope.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbScope.cs index c46220b8..92ac385e 100644 --- a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbScope.cs +++ b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbScope.cs @@ -80,7 +80,7 @@ internal PdbScope(uint funcOffset, BlockSym32 block, BitAccess bits, out uint ty } case SYM.S_MANSLOT: - slots[slot++] = new PdbSlot(bits, out typind); + slots[slot++] = new PdbSlot(bits); bits.Position = stop; break; diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSlot.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSlot.cs similarity index 91% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSlot.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSlot.cs index 0dc89ad4..e2b76d5f 100644 --- a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSlot.cs +++ b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSlot.cs @@ -13,12 +13,13 @@ namespace Microsoft.Cci.Pdb { internal class PdbSlot { internal uint slot; + internal uint typeToken; internal string name; internal ushort flags; //internal uint segment; //internal uint address; - internal PdbSlot(BitAccess bits, out uint typind) { + internal PdbSlot(BitAccess bits) { AttrSlotSym slot; bits.ReadUInt32(out slot.index); @@ -29,12 +30,12 @@ internal PdbSlot(BitAccess bits, out uint typind) { bits.ReadCString(out slot.name); this.slot = slot.index; + this.typeToken = slot.typind; this.name = slot.name; this.flags = slot.flags; //this.segment = slot.segCod; //this.address = slot.offCod; - typind = slot.typind; } } } diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSource.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSource.cs similarity index 100% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSource.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbSource.cs diff --git a/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbTokenLine.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbTokenLine.cs new file mode 100644 index 00000000..879339b2 --- /dev/null +++ b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/PdbTokenLine.cs @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal class PdbTokenLine { + internal uint token; + internal uint file_id; + internal uint line; + internal uint column; + internal uint endLine; + internal uint endColumn; + internal PdbSource sourceFile; + internal PdbTokenLine/*?*/ nextLine; + + internal PdbTokenLine(uint token, uint file_id, uint line, uint column, uint endLine, uint endColumn) { + this.token = token; + this.file_id = file_id; + this.line = line; + this.column = column; + this.endLine = endLine; + this.endColumn = endColumn; + } + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs similarity index 95% rename from Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs rename to Mono.Cecil.Pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs index db3f291b..1c4da186 100644 --- a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs +++ b/Mono.Cecil.Pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs @@ -9,7 +9,6 @@ using Microsoft.Cci; using Microsoft.Cci.Pdb; using System.Text; -using System.Diagnostics.SymbolStore; namespace Microsoft.Cci { diff --git a/Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj b/Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj index 6c4ebc33..eeebce15 100644 --- a/Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj +++ b/Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj @@ -1,87 +1,22 @@  - - + - Debug - AnyCPU - {CEA7A85F-2523-4AD0-8296-6E8E0A2E6DF7} - Library - Properties + {63E6915C-7EA4-4D76-AB28-0D7191EEA626} Mono.Cecil.Pdb Mono.Cecil.Pdb - v2.0 - 512 - + 0649 - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + {D68133BD-1E63-496E-9EDE-4FBDBF77B486} + Mono.Cecil + - - {d3785d8b-4d85-4546-8763-47fc848c13e0} - Mono.Cecil.20 - + + + - - - \ No newline at end of file + + + diff --git a/Mono.Cecil.Pdb/Mono.Cecil.Pdb/AssemblyInfo.cs b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/AssemblyInfo.cs new file mode 100644 index 00000000..c4b4e2e9 --- /dev/null +++ b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/AssemblyInfo.cs @@ -0,0 +1,16 @@ +// +// 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.Reflection; + +[assembly: AssemblyTitle ("Mono.Cecil.Pdb")] + +[assembly: CLSCompliant (false)] diff --git a/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs new file mode 100644 index 00000000..f694e270 --- /dev/null +++ b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs @@ -0,0 +1,22 @@ +// Author: +// Juerg Billeter (j@bitron.ch) +// +// (C) 2008 Juerg Billeter +// +// Licensed under the MIT/X11 license. +// + +using System.Runtime.InteropServices; + +#if !READ_ONLY + +namespace Mono.Cecil.Pdb { + + [Guid ("B01FAFEB-C450-3A4D-BEEC-B4CEEC01E006")] + [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + interface ISymUnmanagedDocumentWriter { + } +} + +#endif diff --git a/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs new file mode 100644 index 00000000..81cc6a3a --- /dev/null +++ b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs @@ -0,0 +1,90 @@ +// +// Author: +// Juerg Billeter (j@bitron.ch) +// +// (C) 2008 Juerg Billeter +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; + +using Mono.Cecil.Cil; + +#if !READ_ONLY + +namespace Mono.Cecil.Pdb { + + [Guid ("0B97726E-9E6D-4f05-9A26-424022093CAA")] + [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + interface ISymUnmanagedWriter2 { + + void DefineDocument ( + [In, MarshalAs (UnmanagedType.LPWStr)] string url, + [In] ref Guid langauge, + [In] ref Guid languageVendor, + [In] ref Guid documentType, + [Out, MarshalAs (UnmanagedType.Interface)] out ISymUnmanagedDocumentWriter pRetVal); + void SetUserEntryPoint ([In] int methodToken); + void OpenMethod ([In] int methodToken); + void CloseMethod (); + void OpenScope ([In] int startOffset, [Out] out int pRetVal); + void CloseScope ([In] int endOffset); + void SetScopeRange_Placeholder (); + void DefineLocalVariable_Placeholder (); + void DefineParameter_Placeholder (); + void DefineField_Placeholder (); + void DefineGlobalVariable_Placeholder (); + void Close (); + void SetSymAttribute (uint parent, string name, uint data, IntPtr signature); + void OpenNamespace ([In, MarshalAs (UnmanagedType.LPWStr)] string name); + void CloseNamespace (); + void UsingNamespace ([In, MarshalAs (UnmanagedType.LPWStr)] string fullName); + void SetMethodSourceRange_Placeholder (); + void Initialize ( + [In, MarshalAs (UnmanagedType.IUnknown)] object emitter, + [In, MarshalAs (UnmanagedType.LPWStr)] string filename, + [In] IStream pIStream, + [In] bool fFullBuild); + void GetDebugInfo ( + [Out] out ImageDebugDirectory pIDD, + [In] int cData, + [Out] out int pcData, + [In, Out, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] byte [] data); + void DefineSequencePoints ( + [In, MarshalAs (UnmanagedType.Interface)] ISymUnmanagedDocumentWriter document, + [In] int spCount, + [In, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] int [] offsets, + [In, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] int [] lines, + [In, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] int [] columns, + [In, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] int [] endLines, + [In, MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 1)] int [] endColumns); + void RemapToken_Placeholder (); + void Initialize2_Placeholder (); + void DefineConstant_Placeholder (); + void Abort_Placeholder (); + + void DefineLocalVariable2 ( + [In, MarshalAs (UnmanagedType.LPWStr)] string name, + [In] int attributes, + [In] int sigToken, + [In] int addrKind, + [In] int addr1, + [In] int addr2, + [In] int addr3, + [In] int startOffset, + [In] int endOffset); + + void DefineGlobalVariable2_Placeholder (); + + void DefineConstant2 ( + [In, MarshalAs (UnmanagedType.LPWStr)] string name, + [In, MarshalAs (UnmanagedType.Struct)] object variant, + [In] int sigToken); + } +} + +#endif diff --git a/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ModuleMetadata.cs b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ModuleMetadata.cs new file mode 100644 index 00000000..b175c06a --- /dev/null +++ b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/ModuleMetadata.cs @@ -0,0 +1,796 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +#if !READ_ONLY + +namespace Mono.Cecil.Pdb { + + [ComImport, InterfaceType (ComInterfaceType.InterfaceIsIUnknown), Guid ("BA3FEE4C-ECB9-4e41-83B7-183FA41CD859")] + interface IMetaDataEmit { + void SetModuleProps (string szName); + void Save (string szFile, uint dwSaveFlags); + void SaveToStream (IntPtr pIStream, uint dwSaveFlags); + uint GetSaveSize (uint fSave); + uint DefineTypeDef (IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements); + uint DefineNestedType (IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements, uint tdEncloser); + void SetHandler ([MarshalAs (UnmanagedType.IUnknown), In]object pUnk); + uint DefineMethod (uint td, IntPtr zName, uint dwMethodFlags, IntPtr pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags); + void DefineMethodImpl (uint td, uint tkBody, uint tkDecl); + uint DefineTypeRefByName (uint tkResolutionScope, IntPtr szName); + uint DefineImportType (IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, + uint tdImport, IntPtr pAssemEmit); + uint DefineMemberRef (uint tkImport, string szName, IntPtr pvSigBlob, uint cbSigBlob); + uint DefineImportMember (IntPtr pAssemImport, IntPtr /* void* */ pbHashValue, uint cbHashValue, + IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent); + uint DefineEvent (uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr /* uint* */ rmdOtherMethods); + void SetClassLayout (uint td, uint dwPackSize, IntPtr /*COR_FIELD_OFFSET**/ rFieldOffsets, uint ulClassSize); + void DeleteClassLayout (uint td); + void SetFieldMarshal (uint tk, IntPtr /* byte* */ pvNativeType, uint cbNativeType); + void DeleteFieldMarshal (uint tk); + uint DefinePermissionSet (uint tk, uint dwAction, IntPtr /* void* */ pvPermission, uint cbPermission); + void SetRVA (uint md, uint ulRVA); + uint GetTokenFromSig (IntPtr /* byte* */ pvSig, uint cbSig); + uint DefineModuleRef (string szName); + void SetParent (uint mr, uint tk); + uint GetTokenFromTypeSpec (IntPtr /* byte* */ pvSig, uint cbSig); + void SaveToMemory (IntPtr /* void* */ pbData, uint cbData); + uint DefineUserString (string szString, uint cchString); + void DeleteToken (uint tkObj); + void SetMethodProps (uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags); + void SetTypeDefProps (uint td, uint dwTypeDefFlags, uint tkExtends, IntPtr /* uint* */ rtkImplements); + void SetEventProps (uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr /* uint* */ rmdOtherMethods); + uint SetPermissionSetProps (uint tk, uint dwAction, IntPtr /* void* */ pvPermission, uint cbPermission); + void DefinePinvokeMap (uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL); + void SetPinvokeMap (uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL); + void DeletePinvokeMap (uint tk); + uint DefineCustomAttribute (uint tkObj, uint tkType, IntPtr /* void* */ pCustomAttribute, uint cbCustomAttribute); + void SetCustomAttributeValue (uint pcv, IntPtr /* void* */ pCustomAttribute, uint cbCustomAttribute); + uint DefineField (uint td, string szName, uint dwFieldFlags, IntPtr /* byte* */ pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag, IntPtr /* void* */ pValue, uint cchValue); + uint DefineProperty (uint td, string szProperty, uint dwPropFlags, IntPtr /* byte* */ pvSig, uint cbSig, uint dwCPlusTypeFlag, + IntPtr /* void* */ pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr /* uint* */ rmdOtherMethods); + uint DefineParam (uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr /* void* */ pValue, uint cchValue); + void SetFieldProps (uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, IntPtr /* void* */ pValue, uint cchValue); + void SetPropertyProps (uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, IntPtr /* void* */ pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr /* uint* */ rmdOtherMethods); + void SetParamProps (uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr /* void* */ pValue, uint cchValue); + uint DefineSecurityAttributeSet (uint tkObj, IntPtr rSecAttrs, uint cSecAttrs); + void ApplyEditAndContinue ([MarshalAs (UnmanagedType.IUnknown)]object pImport); + uint TranslateSigWithScope (IntPtr pAssemImport, IntPtr /* void* */ pbHashValue, uint cbHashValue, + IMetaDataImport import, IntPtr /* byte* */ pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, IntPtr /* byte* */ pvTranslatedSig, uint cbTranslatedSigMax); + void SetMethodImplFlags (uint md, uint dwImplFlags); + void SetFieldRVA (uint fd, uint ulRVA); + void Merge (IMetaDataImport pImport, IntPtr pHostMapToken, [MarshalAs (UnmanagedType.IUnknown)]object pHandler); + void MergeEnd (); + } + + [ComImport, InterfaceType (ComInterfaceType.InterfaceIsIUnknown), Guid ("7DAC8207-D3AE-4c75-9B67-92801A497D44")] + interface IMetaDataImport { + [PreserveSig] + void CloseEnum (uint hEnum); + uint CountEnum (uint hEnum); + void ResetEnum (uint hEnum, uint ulPos); + uint EnumTypeDefs (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rTypeDefs, uint cMax); + uint EnumInterfaceImpls (ref uint phEnum, uint td, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] uint [] rImpls, uint cMax); + uint EnumTypeRefs (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rTypeRefs, uint cMax); + uint FindTypeDefByName (string szTypeDef, uint tkEnclosingClass); + Guid GetScopeProps (StringBuilder szName, uint cchName, out uint pchName); + uint GetModuleFromScope (); + uint GetTypeDefProps (uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags); + uint GetInterfaceImplProps (uint iiImpl, out uint pClass); + uint GetTypeRefProps (uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName); + uint ResolveTypeRef (uint tr, [In] ref Guid riid, [MarshalAs (UnmanagedType.Interface)] out object ppIScope); + uint EnumMembers (ref uint phEnum, uint cl, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] uint [] rMembers, uint cMax); + uint EnumMembersWithName (ref uint phEnum, uint cl, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rMembers, uint cMax); + uint EnumMethods (ref uint phEnum, uint cl, IntPtr /* uint* */ rMethods, uint cMax); + uint EnumMethodsWithName (ref uint phEnum, uint cl, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rMethods, uint cMax); + uint EnumFields (ref uint phEnum, uint cl, IntPtr /* uint* */ rFields, uint cMax); + uint EnumFieldsWithName (ref uint phEnum, uint cl, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rFields, uint cMax); + uint EnumParams (ref uint phEnum, uint mb, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] uint [] rParams, uint cMax); + uint EnumMemberRefs (ref uint phEnum, uint tkParent, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] uint [] rMemberRefs, uint cMax); + uint EnumMethodImpls (ref uint phEnum, uint td, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rMethodBody, + [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rMethodDecl, uint cMax); + uint EnumPermissionSets (ref uint phEnum, uint tk, uint dwActions, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rPermission, + uint cMax); + uint FindMember (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob); + uint FindMethod (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob); + uint FindField (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob); + uint FindMemberRef (uint td, string szName, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] byte [] pvSigBlob, uint cbSigBlob); + uint GetMethodProps (uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA); + uint GetMemberRefProps (uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr /* byte* */ ppvSigBlob); + uint EnumProperties (ref uint phEnum, uint td, IntPtr /* uint* */ rProperties, uint cMax); + uint EnumEvents (ref uint phEnum, uint td, IntPtr /* uint* */ rEvents, uint cMax); + uint GetEventProps (uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, + out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, + [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 11)] uint [] rmdOtherMethod, uint cMax); + uint EnumMethodSemantics (ref uint phEnum, uint mb, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] uint [] rEventProp, uint cMax); + uint GetMethodSemantics (uint mb, uint tkEventProp); + uint GetClassLayout (uint td, out uint pdwPackSize, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 3)] IntPtr /*COR_FIELD_OFFSET **/ rFieldOffset, uint cMax, out uint pcFieldOffset); + uint GetFieldMarshal (uint tk, out IntPtr /* byte* */ ppvNativeType); + uint GetRVA (uint tk, out uint pulCodeRVA); + uint GetPermissionSetProps (uint pm, out uint pdwAction, out IntPtr /* void* */ ppvPermission); + uint GetSigFromToken (uint mdSig, out IntPtr /* byte* */ ppvSig); + uint GetModuleRefProps (uint mur, StringBuilder szName, uint cchName); + uint EnumModuleRefs (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rModuleRefs, uint cmax); + uint GetTypeSpecFromToken (uint typespec, out IntPtr /* byte* */ ppvSig); + uint GetNameFromToken (uint tk); + uint EnumUnresolvedMethods (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rMethods, uint cMax); + uint GetUserString (uint stk, StringBuilder szString, uint cchString); + uint GetPinvokeMap (uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName); + uint EnumSignatures (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rSignatures, uint cmax); + uint EnumTypeSpecs (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rTypeSpecs, uint cmax); + uint EnumUserStrings (ref uint phEnum, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 2)] uint [] rStrings, uint cmax); + [PreserveSig] + int GetParamForMethodIndex (uint md, uint ulParamSeq, out uint pParam); + uint EnumCustomAttributes (ref uint phEnum, uint tk, uint tkType, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 4)] uint [] rCustomAttributes, uint cMax); + uint GetCustomAttributeProps (uint cv, out uint ptkObj, out uint ptkType, out IntPtr /* void* */ ppBlob); + uint FindTypeRef (uint tkResolutionScope, string szName); + uint GetMemberProps (uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr, + out IntPtr /* byte* */ ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr /* void* */ ppValue); + uint GetFieldProps (uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr, + out IntPtr /* byte* */ ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr /* void* */ ppValue); + uint GetPropertyProps (uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, + out IntPtr /* byte* */ ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr /* void* */ ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, + out uint pmdGetter, [MarshalAs (UnmanagedType.LPArray, SizeParamIndex = 14)] uint [] rmdOtherMethod, uint cMax); + uint GetParamProps (uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName, + out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr /* void* */ ppValue); + uint GetCustomAttributeByName (uint tkObj, string szName, out IntPtr /* void* */ ppData); + [PreserveSig] + [return: MarshalAs (UnmanagedType.Bool)] + bool IsValidToken (uint tk); + uint GetNestedClassProps (uint tdNestedClass); + uint GetNativeCallConvFromSig (IntPtr /* void* */ pvSig, uint cbSig); + int IsGlobal (uint pd); + } + + class ModuleMetadata : IMetaDataEmit, IMetaDataImport { + + readonly ModuleDefinition module; + + Dictionary types; + Dictionary methods; + + public ModuleMetadata (ModuleDefinition module) + { + this.module = module; + } + + bool TryGetType (uint token, out TypeDefinition type) + { + if (types == null) + InitializeMetadata (module); + + return types.TryGetValue (token, out type); + } + + bool TryGetMethod (uint token, out MethodDefinition method) + { + if (methods == null) + InitializeMetadata (module); + + return methods.TryGetValue (token, out method); + } + + void InitializeMetadata (ModuleDefinition module) + { + types = new Dictionary (); + methods = new Dictionary (); + + foreach (var type in module.GetTypes ()) { + types.Add (type.MetadataToken.ToUInt32 (), type); + InitializeMethods (type); + } + } + + void InitializeMethods (TypeDefinition type) + { + foreach (var method in type.Methods) + methods.Add (method.MetadataToken.ToUInt32 (), method); + } + + public void SetModuleProps (string szName) + { + throw new NotImplementedException (); + } + + public void Save (string szFile, uint dwSaveFlags) + { + throw new NotImplementedException (); + } + + public void SaveToStream (IntPtr pIStream, uint dwSaveFlags) + { + throw new NotImplementedException (); + } + + public uint GetSaveSize (uint fSave) + { + throw new NotImplementedException (); + } + + public uint DefineTypeDef (IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements) + { + throw new NotImplementedException (); + } + + public uint DefineNestedType (IntPtr szTypeDef, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements, uint tdEncloser) + { + throw new NotImplementedException (); + } + + public void SetHandler (object pUnk) + { + throw new NotImplementedException (); + } + + public uint DefineMethod (uint td, IntPtr zName, uint dwMethodFlags, IntPtr pvSigBlob, uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags) + { + throw new NotImplementedException (); + } + + public void DefineMethodImpl (uint td, uint tkBody, uint tkDecl) + { + throw new NotImplementedException (); + } + + public uint DefineTypeRefByName (uint tkResolutionScope, IntPtr szName) + { + throw new NotImplementedException (); + } + + public uint DefineImportType (IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint tdImport, IntPtr pAssemEmit) + { + throw new NotImplementedException (); + } + + public uint DefineMemberRef (uint tkImport, string szName, IntPtr pvSigBlob, uint cbSigBlob) + { + throw new NotImplementedException (); + } + + public uint DefineImportMember (IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport pImport, uint mbMember, IntPtr pAssemEmit, uint tkParent) + { + throw new NotImplementedException (); + } + + public uint DefineEvent (uint td, string szEvent, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods) + { + throw new NotImplementedException (); + } + + public void SetClassLayout (uint td, uint dwPackSize, IntPtr rFieldOffsets, uint ulClassSize) + { + throw new NotImplementedException (); + } + + public void DeleteClassLayout (uint td) + { + throw new NotImplementedException (); + } + + public void SetFieldMarshal (uint tk, IntPtr pvNativeType, uint cbNativeType) + { + throw new NotImplementedException (); + } + + public void DeleteFieldMarshal (uint tk) + { + throw new NotImplementedException (); + } + + public uint DefinePermissionSet (uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission) + { + throw new NotImplementedException (); + } + + public void SetRVA (uint md, uint ulRVA) + { + throw new NotImplementedException (); + } + + public uint GetTokenFromSig (IntPtr pvSig, uint cbSig) + { + throw new NotImplementedException (); + } + + public uint DefineModuleRef (string szName) + { + throw new NotImplementedException (); + } + + public void SetParent (uint mr, uint tk) + { + throw new NotImplementedException (); + } + + public uint GetTokenFromTypeSpec (IntPtr pvSig, uint cbSig) + { + throw new NotImplementedException (); + } + + public void SaveToMemory (IntPtr pbData, uint cbData) + { + throw new NotImplementedException (); + } + + public uint DefineUserString (string szString, uint cchString) + { + throw new NotImplementedException (); + } + + public void DeleteToken (uint tkObj) + { + throw new NotImplementedException (); + } + + public void SetMethodProps (uint md, uint dwMethodFlags, uint ulCodeRVA, uint dwImplFlags) + { + throw new NotImplementedException (); + } + + public void SetTypeDefProps (uint td, uint dwTypeDefFlags, uint tkExtends, IntPtr rtkImplements) + { + throw new NotImplementedException (); + } + + public void SetEventProps (uint ev, uint dwEventFlags, uint tkEventType, uint mdAddOn, uint mdRemoveOn, uint mdFire, IntPtr rmdOtherMethods) + { + throw new NotImplementedException (); + } + + public uint SetPermissionSetProps (uint tk, uint dwAction, IntPtr pvPermission, uint cbPermission) + { + throw new NotImplementedException (); + } + + public void DefinePinvokeMap (uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL) + { + throw new NotImplementedException (); + } + + public void SetPinvokeMap (uint tk, uint dwMappingFlags, string szImportName, uint mrImportDLL) + { + throw new NotImplementedException (); + } + + public void DeletePinvokeMap (uint tk) + { + throw new NotImplementedException (); + } + + public uint DefineCustomAttribute (uint tkObj, uint tkType, IntPtr pCustomAttribute, uint cbCustomAttribute) + { + throw new NotImplementedException (); + } + + public void SetCustomAttributeValue (uint pcv, IntPtr pCustomAttribute, uint cbCustomAttribute) + { + throw new NotImplementedException (); + } + + public uint DefineField (uint td, string szName, uint dwFieldFlags, IntPtr pvSigBlob, uint cbSigBlob, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) + { + throw new NotImplementedException (); + } + + public uint DefineProperty (uint td, string szProperty, uint dwPropFlags, IntPtr pvSig, uint cbSig, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods) + { + throw new NotImplementedException (); + } + + public uint DefineParam (uint md, uint ulParamSeq, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) + { + throw new NotImplementedException (); + } + + public void SetFieldProps (uint fd, uint dwFieldFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) + { + throw new NotImplementedException (); + } + + public void SetPropertyProps (uint pr, uint dwPropFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue, uint mdSetter, uint mdGetter, IntPtr rmdOtherMethods) + { + throw new NotImplementedException (); + } + + public void SetParamProps (uint pd, string szName, uint dwParamFlags, uint dwCPlusTypeFlag, IntPtr pValue, uint cchValue) + { + throw new NotImplementedException (); + } + + public uint DefineSecurityAttributeSet (uint tkObj, IntPtr rSecAttrs, uint cSecAttrs) + { + throw new NotImplementedException (); + } + + public void ApplyEditAndContinue (object pImport) + { + throw new NotImplementedException (); + } + + public uint TranslateSigWithScope (IntPtr pAssemImport, IntPtr pbHashValue, uint cbHashValue, IMetaDataImport import, IntPtr pbSigBlob, uint cbSigBlob, IntPtr pAssemEmit, IMetaDataEmit emit, IntPtr pvTranslatedSig, uint cbTranslatedSigMax) + { + throw new NotImplementedException (); + } + + public void SetMethodImplFlags (uint md, uint dwImplFlags) + { + throw new NotImplementedException (); + } + + public void SetFieldRVA (uint fd, uint ulRVA) + { + throw new NotImplementedException (); + } + + public void Merge (IMetaDataImport pImport, IntPtr pHostMapToken, object pHandler) + { + throw new NotImplementedException (); + } + + public void MergeEnd () + { + throw new NotImplementedException (); + } + + public void CloseEnum (uint hEnum) + { + throw new NotImplementedException (); + } + + public uint CountEnum (uint hEnum) + { + throw new NotImplementedException (); + } + + public void ResetEnum (uint hEnum, uint ulPos) + { + throw new NotImplementedException (); + } + + public uint EnumTypeDefs (ref uint phEnum, uint[] rTypeDefs, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumInterfaceImpls (ref uint phEnum, uint td, uint[] rImpls, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumTypeRefs (ref uint phEnum, uint[] rTypeRefs, uint cMax) + { + throw new NotImplementedException (); + } + + public uint FindTypeDefByName (string szTypeDef, uint tkEnclosingClass) + { + throw new NotImplementedException (); + } + + public Guid GetScopeProps (StringBuilder szName, uint cchName, out uint pchName) + { + throw new NotImplementedException (); + } + + public uint GetModuleFromScope () + { + throw new NotImplementedException (); + } + + public uint GetTypeDefProps (uint td, IntPtr szTypeDef, uint cchTypeDef, out uint pchTypeDef, IntPtr pdwTypeDefFlags) + { + TypeDefinition type; + if (!TryGetType (td, out type)) { + Marshal.WriteInt16 (szTypeDef, 0); + pchTypeDef = 1; + return 0; + } + + WriteString (type.IsNested ? type.Name : type.FullName, szTypeDef, cchTypeDef, out pchTypeDef); + WriteIntPtr (pdwTypeDefFlags, (uint) type.Attributes); + return type.BaseType != null ? type.BaseType.MetadataToken.ToUInt32 () : 0; + } + + static void WriteIntPtr (IntPtr ptr, uint value) + { + if (ptr == IntPtr.Zero) + return; + + Marshal.WriteInt32 (ptr, (int) value); + } + + static void WriteString (string str, IntPtr buffer, uint bufferSize, out uint chars) + { + var length = str.Length + 1 >= bufferSize ? bufferSize - 1 : (uint) str.Length; + chars = length + 1; + var offset = 0; + + for (int i = 0; i < length; i++) { + Marshal.WriteInt16 (buffer, offset, str [i]); + offset += 2; + } + + Marshal.WriteInt16 (buffer, offset, 0); + } + + public uint GetInterfaceImplProps (uint iiImpl, out uint pClass) + { + throw new NotImplementedException (); + } + + public uint GetTypeRefProps (uint tr, out uint ptkResolutionScope, StringBuilder szName, uint cchName) + { + throw new NotImplementedException (); + } + + public uint ResolveTypeRef (uint tr, ref Guid riid, out object ppIScope) + { + throw new NotImplementedException (); + } + + public uint EnumMembers (ref uint phEnum, uint cl, uint[] rMembers, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumMembersWithName (ref uint phEnum, uint cl, string szName, uint[] rMembers, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumMethods (ref uint phEnum, uint cl, IntPtr rMethods, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumMethodsWithName (ref uint phEnum, uint cl, string szName, uint[] rMethods, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumFields (ref uint phEnum, uint cl, IntPtr rFields, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumFieldsWithName (ref uint phEnum, uint cl, string szName, uint[] rFields, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumParams (ref uint phEnum, uint mb, uint[] rParams, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumMemberRefs (ref uint phEnum, uint tkParent, uint[] rMemberRefs, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumMethodImpls (ref uint phEnum, uint td, uint[] rMethodBody, uint[] rMethodDecl, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumPermissionSets (ref uint phEnum, uint tk, uint dwActions, uint[] rPermission, uint cMax) + { + throw new NotImplementedException (); + } + + public uint FindMember (uint td, string szName, byte[] pvSigBlob, uint cbSigBlob) + { + throw new NotImplementedException (); + } + + public uint FindMethod (uint td, string szName, byte[] pvSigBlob, uint cbSigBlob) + { + throw new NotImplementedException (); + } + + public uint FindField (uint td, string szName, byte[] pvSigBlob, uint cbSigBlob) + { + throw new NotImplementedException (); + } + + public uint FindMemberRef (uint td, string szName, byte[] pvSigBlob, uint cbSigBlob) + { + throw new NotImplementedException (); + } + + public uint GetMethodProps (uint mb, out uint pClass, IntPtr szMethod, uint cchMethod, out uint pchMethod, IntPtr pdwAttr, IntPtr ppvSigBlob, IntPtr pcbSigBlob, IntPtr pulCodeRVA) + { + MethodDefinition method; + if (!TryGetMethod (mb, out method)) { + Marshal.WriteInt16 (szMethod, 0); + pchMethod = 1; + pClass = 0; + return 0; + } + + pClass = method.DeclaringType.MetadataToken.ToUInt32 (); + WriteString (method.Name, szMethod, cchMethod, out pchMethod); + WriteIntPtr (pdwAttr, (uint) method.Attributes); + WriteIntPtr (pulCodeRVA, (uint) method.RVA); + + return (uint) method.ImplAttributes; + } + + public uint GetMemberRefProps (uint mr, ref uint ptk, StringBuilder szMember, uint cchMember, out uint pchMember, out IntPtr ppvSigBlob) + { + throw new NotImplementedException (); + } + + public uint EnumProperties (ref uint phEnum, uint td, IntPtr rProperties, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumEvents (ref uint phEnum, uint td, IntPtr rEvents, uint cMax) + { + throw new NotImplementedException (); + } + + public uint GetEventProps (uint ev, out uint pClass, StringBuilder szEvent, uint cchEvent, out uint pchEvent, out uint pdwEventFlags, out uint ptkEventType, out uint pmdAddOn, out uint pmdRemoveOn, out uint pmdFire, uint[] rmdOtherMethod, uint cMax) + { + throw new NotImplementedException (); + } + + public uint EnumMethodSemantics (ref uint phEnum, uint mb, uint[] rEventProp, uint cMax) + { + throw new NotImplementedException (); + } + + public uint GetMethodSemantics (uint mb, uint tkEventProp) + { + throw new NotImplementedException (); + } + + public uint GetClassLayout (uint td, out uint pdwPackSize, IntPtr rFieldOffset, uint cMax, out uint pcFieldOffset) + { + throw new NotImplementedException (); + } + + public uint GetFieldMarshal (uint tk, out IntPtr ppvNativeType) + { + throw new NotImplementedException (); + } + + public uint GetRVA (uint tk, out uint pulCodeRVA) + { + throw new NotImplementedException (); + } + + public uint GetPermissionSetProps (uint pm, out uint pdwAction, out IntPtr ppvPermission) + { + throw new NotImplementedException (); + } + + public uint GetSigFromToken (uint mdSig, out IntPtr ppvSig) + { + throw new NotImplementedException (); + } + + public uint GetModuleRefProps (uint mur, StringBuilder szName, uint cchName) + { + throw new NotImplementedException (); + } + + public uint EnumModuleRefs (ref uint phEnum, uint[] rModuleRefs, uint cmax) + { + throw new NotImplementedException (); + } + + public uint GetTypeSpecFromToken (uint typespec, out IntPtr ppvSig) + { + throw new NotImplementedException (); + } + + public uint GetNameFromToken (uint tk) + { + throw new NotImplementedException (); + } + + public uint EnumUnresolvedMethods (ref uint phEnum, uint[] rMethods, uint cMax) + { + throw new NotImplementedException (); + } + + public uint GetUserString (uint stk, StringBuilder szString, uint cchString) + { + throw new NotImplementedException (); + } + + public uint GetPinvokeMap (uint tk, out uint pdwMappingFlags, StringBuilder szImportName, uint cchImportName, out uint pchImportName) + { + throw new NotImplementedException (); + } + + public uint EnumSignatures (ref uint phEnum, uint[] rSignatures, uint cmax) + { + throw new NotImplementedException (); + } + + public uint EnumTypeSpecs (ref uint phEnum, uint[] rTypeSpecs, uint cmax) + { + throw new NotImplementedException (); + } + + public uint EnumUserStrings (ref uint phEnum, uint[] rStrings, uint cmax) + { + throw new NotImplementedException (); + } + + public int GetParamForMethodIndex (uint md, uint ulParamSeq, out uint pParam) + { + throw new NotImplementedException (); + } + + public uint EnumCustomAttributes (ref uint phEnum, uint tk, uint tkType, uint[] rCustomAttributes, uint cMax) + { + throw new NotImplementedException (); + } + + public uint GetCustomAttributeProps (uint cv, out uint ptkObj, out uint ptkType, out IntPtr ppBlob) + { + throw new NotImplementedException (); + } + + public uint FindTypeRef (uint tkResolutionScope, string szName) + { + throw new NotImplementedException (); + } + + public uint GetMemberProps (uint mb, out uint pClass, StringBuilder szMember, uint cchMember, out uint pchMember, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pulCodeRVA, out uint pdwImplFlags, out uint pdwCPlusTypeFlag, out IntPtr ppValue) + { + throw new NotImplementedException (); + } + + public uint GetFieldProps (uint mb, out uint pClass, StringBuilder szField, uint cchField, out uint pchField, out uint pdwAttr, out IntPtr ppvSigBlob, out uint pcbSigBlob, out uint pdwCPlusTypeFlag, out IntPtr ppValue) + { + throw new NotImplementedException (); + } + + public uint GetPropertyProps (uint prop, out uint pClass, StringBuilder szProperty, uint cchProperty, out uint pchProperty, out uint pdwPropFlags, out IntPtr ppvSig, out uint pbSig, out uint pdwCPlusTypeFlag, out IntPtr ppDefaultValue, out uint pcchDefaultValue, out uint pmdSetter, out uint pmdGetter, uint[] rmdOtherMethod, uint cMax) + { + throw new NotImplementedException (); + } + + public uint GetParamProps (uint tk, out uint pmd, out uint pulSequence, StringBuilder szName, uint cchName, out uint pchName, out uint pdwAttr, out uint pdwCPlusTypeFlag, out IntPtr ppValue) + { + throw new NotImplementedException (); + } + + public uint GetCustomAttributeByName (uint tkObj, string szName, out IntPtr ppData) + { + throw new NotImplementedException (); + } + + public bool IsValidToken (uint tk) + { + throw new NotImplementedException (); + } + + public uint GetNestedClassProps (uint tdNestedClass) + { + TypeDefinition type; + if (!TryGetType (tdNestedClass, out type)) + return 0; + + return type.IsNested ? type.DeclaringType.MetadataToken.ToUInt32 () : 0; + } + + public uint GetNativeCallConvFromSig (IntPtr pvSig, uint cbSig) + { + throw new NotImplementedException (); + } + + public int IsGlobal (uint pd) + { + throw new NotImplementedException (); + } + } +} + +#endif diff --git a/Mono.Cecil.Pdb/Mono.Cecil.Pdb/NativePdbReader.cs b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/NativePdbReader.cs new file mode 100644 index 00000000..b07191db --- /dev/null +++ b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/NativePdbReader.cs @@ -0,0 +1,357 @@ +// +// 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 Microsoft.Cci.Pdb; + +using Mono.Cecil.Cil; + +namespace Mono.Cecil.Pdb { + + public class NativePdbReader : ISymbolReader { + + int age; + Guid guid; + + readonly Disposable pdb_file; + readonly Dictionary documents = new Dictionary (); + readonly Dictionary functions = new Dictionary (); + readonly Dictionary imports = new Dictionary (); + + internal NativePdbReader (Disposable file) + { + this.pdb_file = file; + } + +#if !READ_ONLY + public ISymbolWriterProvider GetWriterProvider () + { + return new NativePdbWriterProvider (); + } +#endif + /* + uint Magic = 0x53445352; + Guid Signature; + uint Age; + string FileName; + */ + + public bool ProcessDebugHeader (ImageDebugHeader header) + { + if (!header.HasEntries) + return false; + + var entry = header.GetCodeViewEntry (); + if (entry == null) + return false; + + var directory = entry.Directory; + + if (directory.Type != ImageDebugType.CodeView) + return false; + if (directory.MajorVersion != 0 || directory.MinorVersion != 0) + return false; + + var data = entry.Data; + + if (data.Length < 24) + return false; + + var magic = ReadInt32 (data, 0); + if (magic != 0x53445352) + return false; + + var guid_bytes = new byte [16]; + Buffer.BlockCopy (data, 4, guid_bytes, 0, 16); + + this.guid = new Guid (guid_bytes); + this.age = ReadInt32 (data, 20); + + return PopulateFunctions (); + } + + static int ReadInt32 (byte [] bytes, int start) + { + return (bytes [start] + | (bytes [start + 1] << 8) + | (bytes [start + 2] << 16) + | (bytes [start + 3] << 24)); + } + + bool PopulateFunctions () + { + using (pdb_file) { + Dictionary tokenToSourceMapping; + string sourceServerData; + int age; + Guid guid; + + var funcs = PdbFile.LoadFunctions (pdb_file.value, out tokenToSourceMapping, out sourceServerData, out age, out guid); + + if (this.guid != guid) + return false; + + foreach (PdbFunction function in funcs) + functions.Add (function.token, function); + } + + return true; + } + + public MethodDebugInformation Read (MethodDefinition method) + { + var method_token = method.MetadataToken; + + PdbFunction function; + if (!functions.TryGetValue (method_token.ToUInt32 (), out function)) + return null; + + var symbol = new MethodDebugInformation (method); + + ReadSequencePoints (function, symbol); + + symbol.scope = !function.scopes.IsNullOrEmpty () + ? ReadScopeAndLocals (function.scopes [0], symbol) + : new ScopeDebugInformation { Start = new InstructionOffset (0), End = new InstructionOffset ((int) function.length) }; + + if (function.tokenOfMethodWhoseUsingInfoAppliesToThisMethod != method.MetadataToken.ToUInt32 () && function.tokenOfMethodWhoseUsingInfoAppliesToThisMethod != 0) + symbol.scope.import = GetImport (function.tokenOfMethodWhoseUsingInfoAppliesToThisMethod, method.Module); + + if (function.scopes.Length > 1) { + for (int i = 1; i < function.scopes.Length; i++) { + var s = ReadScopeAndLocals (function.scopes [i], symbol); + if (!AddScope (symbol.scope.Scopes, s)) + symbol.scope.Scopes.Add (s); + } + } + + if (function.iteratorScopes != null) + foreach (var iterator_scope in function.iteratorScopes) + symbol.CustomDebugInformations.Add (new StateMachineScopeDebugInformation ((int) iterator_scope.Offset, (int) (iterator_scope.Offset + iterator_scope.Length + 1))); + + if (function.synchronizationInformation != null) { + var async_debug_info = new AsyncMethodBodyDebugInformation ((int) function.synchronizationInformation.GeneratedCatchHandlerOffset); + + foreach (var synchronization_point in function.synchronizationInformation.synchronizationPoints) { + async_debug_info.Yields.Add (new InstructionOffset ((int) synchronization_point.SynchronizeOffset)); + async_debug_info.Resumes.Add (new InstructionOffset ((int) synchronization_point.ContinuationOffset)); + } + + symbol.CustomDebugInformations.Add (async_debug_info); + + async_debug_info.MoveNextMethod = method; + symbol.StateMachineKickOffMethod = (MethodDefinition) method.Module.LookupToken ((int) function.synchronizationInformation.kickoffMethodToken); + } + + return symbol; + } + + Collection ReadScopeAndLocals (PdbScope [] scopes, MethodDebugInformation info) + { + var symbols = new Collection (scopes.Length); + + foreach (PdbScope scope in scopes) + if (scope != null) + symbols.Add (ReadScopeAndLocals (scope, info)); + + return symbols; + } + + ScopeDebugInformation ReadScopeAndLocals (PdbScope scope, MethodDebugInformation info) + { + var parent = new ScopeDebugInformation (); + parent.Start = new InstructionOffset ((int) scope.offset); + parent.End = new InstructionOffset ((int) (scope.offset + scope.length)); + + if (!scope.slots.IsNullOrEmpty ()) { + parent.variables = new Collection (scope.slots.Length); + + foreach (PdbSlot slot in scope.slots) { + if (slot.flags == 1) // parameter names + continue; + + var index = (int) slot.slot; + var variable = new VariableDebugInformation (index, slot.name); + if (slot.flags == 4) + variable.IsDebuggerHidden = true; + parent.variables.Add (variable); + } + } + + if (!scope.constants.IsNullOrEmpty ()) { + parent.constants = new Collection (scope.constants.Length); + + foreach (var constant in scope.constants) { + var type = info.Method.Module.Read (constant, (c, r) => r.ReadConstantSignature (new MetadataToken (c.token))); + var value = constant.value; + + // Object "null" is encoded as integer + if (type != null && !type.IsValueType && value is int && (int) value == 0) + value = null; + + parent.constants.Add (new ConstantDebugInformation (constant.name, type, value)); + } + } + + if (!scope.usedNamespaces.IsNullOrEmpty ()) { + ImportDebugInformation import; + if (imports.TryGetValue (scope, out import)) { + parent.import = import; + } else { + import = GetImport (scope, info.Method.Module); + imports.Add (scope, import); + parent.import = import; + } + } + + parent.scopes = ReadScopeAndLocals (scope.scopes, info); + + return parent; + } + + static bool AddScope (Collection scopes, ScopeDebugInformation 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) { + sub_scope.Scopes.Add (scope); + return true; + } + } + + return false; + } + + ImportDebugInformation GetImport (uint token, ModuleDefinition module) + { + PdbFunction function; + if (!functions.TryGetValue (token, out function)) + return null; + + if (function.scopes.Length != 1) + return null; + + var scope = function.scopes [0]; + + ImportDebugInformation import; + if (imports.TryGetValue (scope, out import)) + return import; + + import = GetImport (scope, module); + imports.Add (scope, import); + return import; + } + + static ImportDebugInformation GetImport (PdbScope scope, ModuleDefinition module) + { + if (scope.usedNamespaces.IsNullOrEmpty ()) + return null; + + var import = new ImportDebugInformation (); + + foreach (var used_namespace in scope.usedNamespaces) { + if (string.IsNullOrEmpty (used_namespace)) + continue; + + ImportTarget target = null; + var value = used_namespace.Substring (1); + switch (used_namespace [0]) { + case 'U': + target = new ImportTarget (ImportTargetKind.ImportNamespace) { @namespace = value }; + break; + case 'T': { + var type = module.GetType (value, runtimeName: true); + if (type != null) + target = new ImportTarget (ImportTargetKind.ImportType) { type = type }; + break; + } + case 'A': + var index = used_namespace.IndexOf(' '); + var alias_value = used_namespace.Substring (1, index - 1); + var alias_target_value = used_namespace.Substring (index + 2); + switch (used_namespace [index + 1]) { + case 'U': + target = new ImportTarget (ImportTargetKind.DefineNamespaceAlias) { alias = alias_value, @namespace = alias_target_value }; + break; + case 'T': + var type = module.GetType (alias_target_value, runtimeName: true); + if (type != null) + target = new ImportTarget (ImportTargetKind.DefineTypeAlias) { alias = alias_value, type = type }; + break; + } + break; + } + + if (target != null) + import.Targets.Add (target); + } + + return import; + } + + void ReadSequencePoints (PdbFunction function, MethodDebugInformation info) + { + if (function.lines == null) + return; + + info.sequence_points = new Collection (); + + foreach (PdbLines lines in function.lines) + ReadLines (lines, info); + } + + void ReadLines (PdbLines lines, MethodDebugInformation info) + { + var document = GetDocument (lines.file); + + foreach (var line in lines.lines) + ReadLine (line, document, info); + } + + static void ReadLine (PdbLine line, Document document, MethodDebugInformation info) + { + 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; + + info.sequence_points.Add (sequence_point); + } + + Document GetDocument (PdbSource source) + { + string name = source.name; + Document document; + if (documents.TryGetValue (name, out document)) + return document; + + document = new Document (name) { + Language = source.language.ToLanguage (), + LanguageVendor = source.vendor.ToVendor (), + Type = source.doctype.ToType (), + }; + documents.Add (name, document); + return document; + } + + public void Dispose () + { + pdb_file.Dispose (); + } + } +} diff --git a/Mono.Cecil.Pdb/Mono.Cecil.Pdb/NativePdbWriter.cs b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/NativePdbWriter.cs new file mode 100644 index 00000000..e3d6d178 --- /dev/null +++ b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/NativePdbWriter.cs @@ -0,0 +1,374 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +using Mono.Cecil.Cil; +using Mono.Cecil.PE; +using Mono.Collections.Generic; + +#if !READ_ONLY + +namespace Mono.Cecil.Pdb { + + public class NativePdbWriter : ISymbolWriter, IMetadataSymbolWriter { + + readonly ModuleDefinition module; + readonly SymWriter writer; + readonly Dictionary documents; + readonly Dictionary import_info_to_parent; + + MetadataBuilder metadata; + + internal NativePdbWriter (ModuleDefinition module, SymWriter writer) + { + this.module = module; + this.writer = writer; + this.documents = new Dictionary (); + this.import_info_to_parent = new Dictionary (); + } + + public ISymbolReaderProvider GetReaderProvider () + { + return new NativePdbReaderProvider (); + } + + public ImageDebugHeader GetDebugHeader () + { + ImageDebugDirectory directory; + var data = writer.GetDebugInfo (out directory); + directory.TimeDateStamp = (int) module.timestamp; + return new ImageDebugHeader (new ImageDebugHeaderEntry (directory, data)); + } + + public void Write (MethodDebugInformation info) + { + var method_token = info.method.MetadataToken; + var sym_token = method_token.ToInt32 (); + + if (!info.HasSequencePoints && info.scope == null && !info.HasCustomDebugInformations && info.StateMachineKickOffMethod == null) + return; + + writer.OpenMethod (sym_token); + + if (!info.sequence_points.IsNullOrEmpty ()) + DefineSequencePoints (info.sequence_points); + + var import_parent = new MetadataToken (); + + if (info.scope != null) + DefineScope (info.scope, info, out import_parent); + + DefineCustomMetadata (info, import_parent); + + writer.CloseMethod (); + } + + void IMetadataSymbolWriter.SetMetadata (MetadataBuilder metadata) + { + this.metadata = metadata; + } + + void IMetadataSymbolWriter.WriteModule () + { + } + + void DefineCustomMetadata (MethodDebugInformation info, MetadataToken import_parent) + { + var metadata = new CustomMetadataWriter (this.writer); + + if (import_parent.RID != 0) { + metadata.WriteForwardInfo (import_parent); + } else if (info.scope != null && info.scope.Import != null && info.scope.Import.HasTargets) { + metadata.WriteUsingInfo (info.scope.Import); + } + + if (info.Method.HasCustomAttributes) { + foreach (var attribute in info.Method.CustomAttributes) { + const string compiler_services = "System.Runtime.CompilerServices"; + var attribute_type = attribute.AttributeType; + + if (!attribute_type.IsTypeOf (compiler_services, "IteratorStateMachineAttribute") && !attribute_type.IsTypeOf (compiler_services, "AsyncStateMachineAttribute")) + continue; + + var type = attribute.ConstructorArguments [0].Value as TypeReference; + if (type == null) + continue; + + metadata.WriteForwardIterator (type); + } + } + + if (info.HasCustomDebugInformations) { + var scopes = info.CustomDebugInformations.OfType ().ToArray (); + + if (scopes.Length > 0) + metadata.WriteIteratorScopes (scopes, info); + } + + metadata.WriteCustomMetadata (); + + DefineAsyncCustomMetadata (info); + } + + void DefineAsyncCustomMetadata (MethodDebugInformation info) + { + if (!info.HasCustomDebugInformations) + return; + + foreach (var custom_info in info.CustomDebugInformations) { + var async_debug_info = custom_info as AsyncMethodBodyDebugInformation; + if (async_debug_info == null) + continue; + + using (var stream = new MemoryStream ()) { + var async_metadata = new BinaryStreamWriter (stream); + async_metadata.WriteUInt32 (info.StateMachineKickOffMethod != null ? info.StateMachineKickOffMethod.MetadataToken.ToUInt32 () : 0); + async_metadata.WriteUInt32 ((uint) async_debug_info.CatchHandler.Offset); + async_metadata.WriteUInt32 ((uint) async_debug_info.Resumes.Count); + for (int i = 0; i < async_debug_info.Resumes.Count; ++i) { + async_metadata.WriteUInt32 ((uint) async_debug_info.Yields [i].Offset); + async_metadata.WriteUInt32 (async_debug_info.MoveNextMethod != null ? async_debug_info.MoveNextMethod.MetadataToken.ToUInt32 () : 0); + async_metadata.WriteUInt32 ((uint) async_debug_info.Resumes [i].Offset); + } + + writer.DefineCustomMetadata ("asyncMethodInfo", stream.ToArray ()); + } + } + } + + void DefineScope (ScopeDebugInformation scope, MethodDebugInformation info, out MetadataToken import_parent) + { + var start_offset = scope.Start.Offset; + var end_offset = scope.End.IsEndOfMethod + ? info.code_size + : scope.End.Offset; + + import_parent = new MetadataToken (0u); + + writer.OpenScope (start_offset); + + if (scope.Import != null && scope.Import.HasTargets && !import_info_to_parent.TryGetValue (info.scope.Import, out import_parent)) { + foreach (var target in scope.Import.Targets) { + switch (target.Kind) { + case ImportTargetKind.ImportNamespace: + writer.UsingNamespace ("U" + target.@namespace); + break; + case ImportTargetKind.ImportType: + writer.UsingNamespace ("T" + TypeParser.ToParseable (target.type)); + break; + case ImportTargetKind.DefineNamespaceAlias: + writer.UsingNamespace ("A" + target.Alias + " U" + target.@namespace); + break; + case ImportTargetKind.DefineTypeAlias: + writer.UsingNamespace ("A" + target.Alias + " T" + TypeParser.ToParseable (target.type)); + break; + } + } + + import_info_to_parent.Add (info.scope.Import, info.method.MetadataToken); + } + + var sym_token = info.local_var_token.ToInt32 (); + + if (!scope.variables.IsNullOrEmpty ()) { + for (int i = 0; i < scope.variables.Count; i++) { + var variable = scope.variables [i]; + DefineLocalVariable (variable, sym_token, start_offset, end_offset); + } + } + + if (!scope.constants.IsNullOrEmpty ()) { + for (int i = 0; i < scope.constants.Count; i++) { + var constant = scope.constants [i]; + DefineConstant (constant); + } + } + + if (!scope.scopes.IsNullOrEmpty ()) { + for (int i = 0; i < scope.scopes.Count; i++) { + MetadataToken _; + DefineScope (scope.scopes [i], info, out _); + } + } + + writer.CloseScope (end_offset); + } + + void DefineSequencePoints (Collection sequence_points) + { + for (int i = 0; i < sequence_points.Count; i++) { + var sequence_point = sequence_points [i]; + + writer.DefineSequencePoints ( + GetDocument (sequence_point.Document), + new [] { sequence_point.Offset }, + new [] { sequence_point.StartLine }, + new [] { sequence_point.StartColumn }, + new [] { sequence_point.EndLine }, + new [] { sequence_point.EndColumn }); + } + } + + void DefineLocalVariable (VariableDebugInformation variable, int local_var_token, int start_offset, int end_offset) + { + writer.DefineLocalVariable2 ( + variable.Name, + variable.Attributes, + local_var_token, + variable.Index, + 0, + 0, + start_offset, + end_offset); + } + + void DefineConstant (ConstantDebugInformation constant) + { + var row = metadata.AddStandAloneSignature (metadata.GetConstantTypeBlobIndex (constant.ConstantType)); + var token = new MetadataToken (TokenType.Signature, row); + + writer.DefineConstant2 (constant.Name, constant.Value, token.ToInt32 ()); + } + + SymDocumentWriter GetDocument (Document document) + { + if (document == null) + return null; + + SymDocumentWriter doc_writer; + if (documents.TryGetValue (document.Url, out doc_writer)) + return doc_writer; + + doc_writer = writer.DefineDocument ( + document.Url, + document.Language.ToGuid (), + document.LanguageVendor.ToGuid (), + document.Type.ToGuid ()); + + documents [document.Url] = doc_writer; + return doc_writer; + } + + public void Dispose () + { + var entry_point = module.EntryPoint; + if (entry_point != null) + writer.SetUserEntryPoint (entry_point.MetadataToken.ToInt32 ()); + + writer.Close (); + } + } + + enum CustomMetadataType : byte { + UsingInfo = 0, + ForwardInfo = 1, + IteratorScopes = 3, + ForwardIterator = 4, + } + + class CustomMetadataWriter : IDisposable { + + readonly SymWriter sym_writer; + readonly MemoryStream stream; + readonly BinaryStreamWriter writer; + + int count; + + const byte version = 4; + + public CustomMetadataWriter (SymWriter sym_writer) + { + this.sym_writer = sym_writer; + this.stream = new MemoryStream (); + this.writer = new BinaryStreamWriter (stream); + + writer.WriteByte (version); + writer.WriteByte (0); // count + writer.Align (4); + } + + public void WriteUsingInfo (ImportDebugInformation import_info) + { + Write (CustomMetadataType.UsingInfo, () => { + writer.WriteUInt16 ((ushort) 1); + writer.WriteUInt16 ((ushort) import_info.Targets.Count); + }); + } + + public void WriteForwardInfo (MetadataToken import_parent) + { + Write (CustomMetadataType.ForwardInfo, () => writer.WriteUInt32 (import_parent.ToUInt32 ())); + } + + public void WriteIteratorScopes (StateMachineScopeDebugInformation [] scopes, MethodDebugInformation debug_info) + { + Write (CustomMetadataType.IteratorScopes, () => { + writer.WriteInt32 (scopes.Length); + foreach (var scope in scopes) { + var start = scope.Start.Offset; + var end = scope.End.IsEndOfMethod ? debug_info.code_size : scope.End.Offset; + writer.WriteInt32 (start); + writer.WriteInt32 (end - 1); + } + }); + } + + public void WriteForwardIterator (TypeReference type) + { + Write (CustomMetadataType.ForwardIterator, () => writer.WriteBytes(Encoding.Unicode.GetBytes(type.Name))); + } + + void Write (CustomMetadataType type, Action write) + { + count++; + writer.WriteByte (version); + writer.WriteByte ((byte) type); + writer.Align (4); + + var length_position = writer.Position; + writer.WriteUInt32 (0); + + write (); + writer.Align (4); + + var end = writer.Position; + var length = end - length_position + 4; // header is 4 bytes long + + writer.Position = length_position; + writer.WriteInt32 (length); + + writer.Position = end; + } + + public void WriteCustomMetadata () + { + if (count == 0) + return; + + writer.BaseStream.Position = 1; + writer.WriteByte ((byte) count); + writer.Flush (); + + sym_writer.DefineCustomMetadata ("MD2", stream.ToArray ()); + } + + public void Dispose () + { + stream.Dispose (); + } + } +} + +#endif diff --git a/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbHelper.cs b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbHelper.cs new file mode 100644 index 00000000..eb75f3d1 --- /dev/null +++ b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbHelper.cs @@ -0,0 +1,130 @@ +// +// 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.IO; + +using Mono.Cecil.Cil; + +namespace Mono.Cecil.Pdb { + + public sealed class NativePdbReaderProvider : ISymbolReaderProvider { + + public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + return new NativePdbReader (Disposable.Owned (File.OpenRead (Mixin.GetPdbFileName (fileName)) as Stream)); + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + + return new NativePdbReader (Disposable.NotOwned (symbolStream)); + } + } + + public sealed class PdbReaderProvider : ISymbolReaderProvider { + + public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + if (module.HasDebugHeader) { + var header = module.GetDebugHeader (); + var entry = header.GetEmbeddedPortablePdbEntry (); + if (entry != null) + return new EmbeddedPortablePdbReaderProvider ().GetSymbolReader (module, fileName); + } + + return Mixin.IsPortablePdb (Mixin.GetPdbFileName (fileName)) + ? new PortablePdbReaderProvider ().GetSymbolReader (module, fileName) + : new NativePdbReaderProvider ().GetSymbolReader (module, fileName); + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + Mixin.CheckReadSeek (symbolStream); + + return Mixin.IsPortablePdb (symbolStream) + ? new PortablePdbReaderProvider ().GetSymbolReader (module, symbolStream) + : new NativePdbReaderProvider ().GetSymbolReader (module, symbolStream); + } + } + +#if !READ_ONLY + + public sealed class NativePdbWriterProvider : ISymbolWriterProvider { + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + return new NativePdbWriter (module, CreateWriter (module, Mixin.GetPdbFileName (fileName))); + } + + static SymWriter CreateWriter (ModuleDefinition module, string pdb) + { + var writer = new SymWriter (); + + if (File.Exists (pdb)) + File.Delete (pdb); + + writer.Initialize (new ModuleMetadata (module), pdb, true); + + return writer; + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + throw new NotImplementedException (); + } + } + + public sealed class PdbWriterProvider : ISymbolWriterProvider { + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + if (HasPortablePdbSymbols (module)) + return new PortablePdbWriterProvider ().GetSymbolWriter (module, fileName); + + return new NativePdbWriterProvider ().GetSymbolWriter (module, fileName); + } + + static bool HasPortablePdbSymbols (ModuleDefinition module) + { + return module.symbol_reader != null && module.symbol_reader is PortablePdbReader; + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + Mixin.CheckReadSeek (symbolStream); + + if (HasPortablePdbSymbols (module)) + return new PortablePdbWriterProvider ().GetSymbolWriter (module, symbolStream); + + return new NativePdbWriterProvider ().GetSymbolWriter (module, symbolStream); + } + } + +#endif +} diff --git a/Mono.Cecil.Pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs new file mode 100644 index 00000000..a2bd1a2b --- /dev/null +++ b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs @@ -0,0 +1,32 @@ +// +// Author: +// Juerg Billeter (j@bitron.ch) +// +// (C) 2008 Juerg Billeter +// +// Licensed under the MIT/X11 license. +// + +using System; + +#if !READ_ONLY + +namespace Mono.Cecil.Pdb +{ + internal class SymDocumentWriter + { + readonly ISymUnmanagedDocumentWriter m_unmanagedDocumentWriter; + + public SymDocumentWriter (ISymUnmanagedDocumentWriter unmanagedDocumentWriter) + { + m_unmanagedDocumentWriter = unmanagedDocumentWriter; + } + + public ISymUnmanagedDocumentWriter GetUnmanaged () + { + return m_unmanagedDocumentWriter; + } + } +} + +#endif diff --git a/Mono.Cecil.Pdb/Mono.Cecil.Pdb/SymWriter.cs b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/SymWriter.cs new file mode 100644 index 00000000..5ecf2173 --- /dev/null +++ b/Mono.Cecil.Pdb/Mono.Cecil.Pdb/SymWriter.cs @@ -0,0 +1,160 @@ +// +// Author: +// Juerg Billeter (j@bitron.ch) +// +// (C) 2008 Juerg Billeter +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Runtime.InteropServices; + +using Mono.Cecil.Cil; +using Mono.Collections.Generic; + +#if !READ_ONLY + +namespace Mono.Cecil.Pdb +{ + internal class SymWriter + { + [DllImport("ole32.dll")] + static extern int CoCreateInstance ( + [In] ref Guid rclsid, + [In, MarshalAs (UnmanagedType.IUnknown)] object pUnkOuter, + [In] uint dwClsContext, + [In] ref Guid riid, + [Out, MarshalAs (UnmanagedType.Interface)] out object ppv); + + static Guid s_symUnmangedWriterIID = new Guid("0b97726e-9e6d-4f05-9a26-424022093caa"); + static Guid s_CorSymWriter_SxS_ClassID = new Guid ("108296c1-281e-11d3-bd22-0000f80849bd"); + + readonly ISymUnmanagedWriter2 m_writer; + readonly Collection documents; + + public SymWriter () + { + object objWriter; + CoCreateInstance (ref s_CorSymWriter_SxS_ClassID, null, 1, ref s_symUnmangedWriterIID, out objWriter); + + m_writer = (ISymUnmanagedWriter2) objWriter; + documents = new Collection (); + } + + public byte[] GetDebugInfo (out ImageDebugDirectory idd) + { + int size; + + // get size of debug info + m_writer.GetDebugInfo (out idd, 0, out size, null); + + byte[] debug_info = new byte[size]; + m_writer.GetDebugInfo (out idd, size, out size, debug_info); + + return debug_info; + } + + public void DefineLocalVariable2 ( + string name, + VariableAttributes attributes, + int sigToken, + int addr1, + int addr2, + int addr3, + int startOffset, + int endOffset) + { + m_writer.DefineLocalVariable2 (name, (int)attributes, sigToken, 1 /* ILOffset*/, addr1, addr2, addr3, startOffset, endOffset); + } + + public void DefineConstant2 (string name, object value, int sigToken) + { + if (value == null) { + m_writer.DefineConstant2 (name, 0, sigToken); + return; + } + + m_writer.DefineConstant2 (name, value, sigToken); + } + + public void Close () + { + m_writer.Close (); + Marshal.ReleaseComObject (m_writer); + + foreach (var document in documents) + Marshal.ReleaseComObject (document); + } + + public void CloseMethod () + { + m_writer.CloseMethod (); + } + + public void CloseNamespace () + { + m_writer.CloseNamespace (); + } + + public void CloseScope (int endOffset) + { + m_writer.CloseScope (endOffset); + } + + public SymDocumentWriter DefineDocument (string url, Guid language, Guid languageVendor, Guid documentType) + { + ISymUnmanagedDocumentWriter unmanagedDocumentWriter; + m_writer.DefineDocument (url, ref language, ref languageVendor, ref documentType, out unmanagedDocumentWriter); + + documents.Add (unmanagedDocumentWriter); + return new SymDocumentWriter (unmanagedDocumentWriter); + } + + public void DefineSequencePoints (SymDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) + { + m_writer.DefineSequencePoints (document.GetUnmanaged(), offsets.Length, offsets, lines, columns, endLines, endColumns); + } + + public void Initialize (object emitter, string filename, bool fFullBuild) + { + m_writer.Initialize (emitter, filename, null, fFullBuild); + } + + public void SetUserEntryPoint (int methodToken) + { + m_writer.SetUserEntryPoint (methodToken); + } + + public void OpenMethod (int methodToken) + { + m_writer.OpenMethod (methodToken); + } + + public void OpenNamespace (string name) + { + m_writer.OpenNamespace (name); + } + + public int OpenScope (int startOffset) + { + int result; + m_writer.OpenScope (startOffset, out result); + return result; + } + + public void UsingNamespace (string fullName) + { + m_writer.UsingNamespace (fullName); + } + + public void DefineCustomMetadata (string name, byte [] metadata) + { + var handle = GCHandle.Alloc (metadata, GCHandleType.Pinned); + m_writer.SetSymAttribute (0, name, (uint) metadata.Length, handle.AddrOfPinnedObject ()); + handle.Free (); + } + } +} + +#endif diff --git a/Mono.Cecil.Pdb/Properties/AssemblyInfo.cs b/Mono.Cecil.Pdb/Properties/AssemblyInfo.cs deleted file mode 100644 index aa929945..00000000 --- a/Mono.Cecil.Pdb/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// 有关程序集的常规信息通过以下 -// 特性集控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("Mono.Cecil.Pdb")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Mono.Cecil.Pdb")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 使此程序集中的类型 -// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, -// 则将该类型上的 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID -[assembly: Guid("37439f61-a9af-46e6-8389-746e2ceda89a")] - -// 程序集的版本信息由下面四个值组成: -// -// 主版本 -// 次版本 -// 生成号 -// 修订号 -// -// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, -// 方法是按如下所示使用“*”: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFunction.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFunction.cs deleted file mode 100644 index 4f2e806e..00000000 --- a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFunction.cs +++ /dev/null @@ -1,519 +0,0 @@ -//----------------------------------------------------------------------------- -// -// Copyright (c) Microsoft. All rights reserved. -// This code is licensed under the Microsoft Public License. -// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF -// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY -// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR -// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. -// -//----------------------------------------------------------------------------- -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Microsoft.Cci.Pdb -{ - internal class PdbFunction - { - static internal readonly Guid msilMetaData = new Guid(0xc6ea3fc9, 0x59b3, 0x49d6, 0xbc, 0x25, - 0x09, 0x02, 0xbb, 0xab, 0xb4, 0x60); - static internal readonly IComparer byAddress = new PdbFunctionsByAddress(); - static internal readonly IComparer byAddressAndToken = new PdbFunctionsByAddressAndToken(); - //static internal readonly IComparer byToken = new PdbFunctionsByToken(); - - internal uint token; - internal uint slotToken; - //internal string name; - //internal string module; - //internal ushort flags; - - internal uint segment; - internal uint address; - //internal uint length; - - //internal byte[] metadata; - internal PdbScope[] scopes; - internal PdbSlot[] slots; - internal PdbConstant[] constants; - internal string[] usedNamespaces; - internal PdbLines[] lines; - internal ushort[]/*?*/ usingCounts; - internal IEnumerable/*?*/ namespaceScopes; - internal string/*?*/ iteratorClass; - internal List/*?*/ iteratorScopes; - - private static string StripNamespace(string module) - { - int li = module.LastIndexOf('.'); - if (li > 0) - { - return module.Substring(li + 1); - } - return module; - } - - - internal static PdbFunction[] LoadManagedFunctions(/*string module,*/ - BitAccess bits, uint limit, - bool readStrings) - { - //string mod = StripNamespace(module); - int begin = bits.Position; - int count = 0; - - while (bits.Position < limit) - { - ushort siz; - ushort rec; - - bits.ReadUInt16(out siz); - int star = bits.Position; - int stop = bits.Position + siz; - bits.Position = star; - bits.ReadUInt16(out rec); - - switch ((SYM)rec) - { - case SYM.S_GMANPROC: - case SYM.S_LMANPROC: - ManProcSym proc; - bits.ReadUInt32(out proc.parent); - bits.ReadUInt32(out proc.end); - bits.Position = (int)proc.end; - count++; - break; - - case SYM.S_END: - bits.Position = stop; - break; - - default: - //Console.WriteLine("{0,6}: {1:x2} {2}", - // bits.Position, rec, (SYM)rec); - bits.Position = stop; - break; - } - } - if (count == 0) - { - return null; - } - - bits.Position = begin; - PdbFunction[] funcs = new PdbFunction[count]; - int func = 0; - - while (bits.Position < limit) - { - ushort siz; - ushort rec; - - bits.ReadUInt16(out siz); - int star = bits.Position; - int stop = bits.Position + siz; - bits.ReadUInt16(out rec); - - switch ((SYM)rec) - { - - case SYM.S_GMANPROC: - case SYM.S_LMANPROC: - ManProcSym proc; - //int offset = bits.Position; - - bits.ReadUInt32(out proc.parent); - bits.ReadUInt32(out proc.end); - bits.ReadUInt32(out proc.next); - bits.ReadUInt32(out proc.len); - bits.ReadUInt32(out proc.dbgStart); - bits.ReadUInt32(out proc.dbgEnd); - bits.ReadUInt32(out proc.token); - bits.ReadUInt32(out proc.off); - bits.ReadUInt16(out proc.seg); - bits.ReadUInt8(out proc.flags); - bits.ReadUInt16(out proc.retReg); - if (readStrings) - { - bits.ReadCString(out proc.name); - } - else - { - bits.SkipCString(out proc.name); - } - //Console.WriteLine("token={0:X8} [{1}::{2}]", proc.token, module, proc.name); - - bits.Position = stop; - funcs[func++] = new PdbFunction(/*module,*/ proc, bits); - break; - - default: - { - //throw new PdbDebugException("Unknown SYMREC {0}", (SYM)rec); - bits.Position = stop; - break; - } - } - } - return funcs; - } - - internal static void CountScopesAndSlots(BitAccess bits, uint limit, - out int constants, out int scopes, out int slots, out int usedNamespaces) - { - int pos = bits.Position; - BlockSym32 block; - constants = 0; - slots = 0; - scopes = 0; - usedNamespaces = 0; - - while (bits.Position < limit) - { - ushort siz; - ushort rec; - - bits.ReadUInt16(out siz); - int star = bits.Position; - int stop = bits.Position + siz; - bits.Position = star; - bits.ReadUInt16(out rec); - - switch ((SYM)rec) - { - case SYM.S_BLOCK32: - { - bits.ReadUInt32(out block.parent); - bits.ReadUInt32(out block.end); - - scopes++; - bits.Position = (int)block.end; - break; - } - - case SYM.S_MANSLOT: - slots++; - bits.Position = stop; - break; - - case SYM.S_UNAMESPACE: - usedNamespaces++; - bits.Position = stop; - break; - - case SYM.S_MANCONSTANT: - constants++; - bits.Position = stop; - break; - - default: - bits.Position = stop; - break; - } - } - bits.Position = pos; - } - - internal PdbFunction() - { - } - - internal PdbFunction(/*string module, */ManProcSym proc, BitAccess bits) - { - this.token = proc.token; - //this.module = module; - //this.name = proc.name; - //this.flags = proc.flags; - this.segment = proc.seg; - this.address = proc.off; - //this.length = proc.len; - - if (proc.seg != 1) - { - throw new PdbDebugException("Segment is {0}, not 1.", proc.seg); - } - if (proc.parent != 0 || proc.next != 0) - { - throw new PdbDebugException("Warning parent={0}, next={1}", - proc.parent, proc.next); - } - //if (proc.dbgStart != 0 || proc.dbgEnd != 0) { - // throw new PdbDebugException("Warning DBG start={0}, end={1}", - // proc.dbgStart, proc.dbgEnd); - //} - - int constantCount; - int scopeCount; - int slotCount; - int usedNamespacesCount; - CountScopesAndSlots(bits, proc.end, out constantCount, out scopeCount, out slotCount, out usedNamespacesCount); - int scope = constantCount > 0 || slotCount > 0 || usedNamespacesCount > 0 ? 1 : 0; - int slot = 0; - int constant = 0; - int usedNs = 0; - scopes = new PdbScope[scopeCount + scope]; - slots = new PdbSlot[slotCount]; - constants = new PdbConstant[constantCount]; - usedNamespaces = new string[usedNamespacesCount]; - - if (scope > 0) - scopes[0] = new PdbScope(this.address, proc.len, slots, constants, usedNamespaces); - - while (bits.Position < proc.end) - { - ushort siz; - ushort rec; - - bits.ReadUInt16(out siz); - int star = bits.Position; - int stop = bits.Position + siz; - bits.Position = star; - bits.ReadUInt16(out rec); - - switch ((SYM)rec) - { - case SYM.S_OEM: - { // 0x0404 - OemSymbol oem; - - bits.ReadGuid(out oem.idOem); - bits.ReadUInt32(out oem.typind); - // internal byte[] rgl; // user data, force 4-byte alignment - - if (oem.idOem == msilMetaData) - { - string name = bits.ReadString(); - if (name == "MD2") - { - byte version; - bits.ReadUInt8(out version); - if (version == 4) - { - byte count; - bits.ReadUInt8(out count); - bits.Align(4); - while (count-- > 0) - this.ReadCustomMetadata(bits); - } - } - bits.Position = stop; - break; - } - else - { - throw new PdbDebugException("OEM section: guid={0} ti={1}", - oem.idOem, oem.typind); - // bits.Position = stop; - } - } - - case SYM.S_BLOCK32: - { - BlockSym32 block = new BlockSym32(); - - bits.ReadUInt32(out block.parent); - bits.ReadUInt32(out block.end); - bits.ReadUInt32(out block.len); - bits.ReadUInt32(out block.off); - bits.ReadUInt16(out block.seg); - bits.SkipCString(out block.name); - bits.Position = stop; - - scopes[scope++] = new PdbScope(this.address, block, bits, out slotToken); - bits.Position = (int)block.end; - break; - } - - case SYM.S_MANSLOT: - uint typind; - slots[slot++] = new PdbSlot(bits, out typind); - bits.Position = stop; - break; - - case SYM.S_MANCONSTANT: - constants[constant++] = new PdbConstant(bits); - bits.Position = stop; - break; - - case SYM.S_UNAMESPACE: - bits.ReadCString(out usedNamespaces[usedNs++]); - bits.Position = stop; - break; - - case SYM.S_END: - bits.Position = stop; - break; - - default: - { - //throw new PdbDebugException("Unknown SYM: {0}", (SYM)rec); - bits.Position = stop; - break; - } - } - } - - if (bits.Position != proc.end) - { - throw new PdbDebugException("Not at S_END"); - } - - ushort esiz; - ushort erec; - bits.ReadUInt16(out esiz); - bits.ReadUInt16(out erec); - - if (erec != (ushort)SYM.S_END) - { - throw new PdbDebugException("Missing S_END"); - } - } - - private void ReadCustomMetadata(BitAccess bits) - { - int savedPosition = bits.Position; - byte version; - bits.ReadUInt8(out version); - if (version != 4) - { - throw new PdbDebugException("Unknown custom metadata item version: {0}", version); - } - byte kind; - bits.ReadUInt8(out kind); - bits.Align(4); - uint numberOfBytesInItem; - bits.ReadUInt32(out numberOfBytesInItem); - switch (kind) - { - case 0: this.ReadUsingInfo(bits); break; - case 1: break; // this.ReadForwardInfo(bits); break; - case 2: break; // this.ReadForwardedToModuleInfo(bits); break; - case 3: this.ReadIteratorLocals(bits); break; - case 4: this.ReadForwardIterator(bits); break; - case 6: break; //vs2015 thing - case 7: break; //vs2015 thing - default: - throw new PdbDebugException("Unknown custom metadata item kind: {0}", kind); - } - bits.Position = savedPosition + (int)numberOfBytesInItem; - } - - private void ReadForwardIterator(BitAccess bits) - { - this.iteratorClass = bits.ReadString(); - } - - private void ReadIteratorLocals(BitAccess bits) - { - uint numberOfLocals; - bits.ReadUInt32(out numberOfLocals); - this.iteratorScopes = new List((int)numberOfLocals); - while (numberOfLocals-- > 0) - { - uint ilStartOffset; - uint ilEndOffset; - bits.ReadUInt32(out ilStartOffset); - bits.ReadUInt32(out ilEndOffset); - this.iteratorScopes.Add(new PdbIteratorScope(ilStartOffset, ilEndOffset - ilStartOffset)); - } - } - - //private void ReadForwardedToModuleInfo(BitAccess bits) { - //} - - //private void ReadForwardInfo(BitAccess bits) { - //} - - private void ReadUsingInfo(BitAccess bits) - { - ushort numberOfNamespaces; - bits.ReadUInt16(out numberOfNamespaces); - this.usingCounts = new ushort[numberOfNamespaces]; - for (ushort i = 0; i < numberOfNamespaces; i++) - { - bits.ReadUInt16(out this.usingCounts[i]); - } - } - - internal class PdbFunctionsByAddress : IComparer - { - public int Compare(Object x, Object y) - { - PdbFunction fx = (PdbFunction)x; - PdbFunction fy = (PdbFunction)y; - - if (fx.segment < fy.segment) - { - return -1; - } - else if (fx.segment > fy.segment) - { - return 1; - } - else if (fx.address < fy.address) - { - return -1; - } - else if (fx.address > fy.address) - { - return 1; - } - else - { - return 0; - } - } - } - - internal class PdbFunctionsByAddressAndToken : IComparer - { - public int Compare(Object x, Object y) - { - PdbFunction fx = (PdbFunction)x; - PdbFunction fy = (PdbFunction)y; - - if (fx.segment < fy.segment) - { - return -1; - } - else if (fx.segment > fy.segment) - { - return 1; - } - else if (fx.address < fy.address) - { - return -1; - } - else if (fx.address > fy.address) - { - return 1; - } - else - { - if (fx.token < fy.token) - return -1; - else if (fx.token > fy.token) - return 1; - else - return 0; - } - } - } - - //internal class PdbFunctionsByToken : IComparer { - // public int Compare(Object x, Object y) { - // PdbFunction fx = (PdbFunction)x; - // PdbFunction fy = (PdbFunction)y; - - // if (fx.token < fy.token) { - // return -1; - // } else if (fx.token > fy.token) { - // return 1; - // } else { - // return 0; - // } - // } - - //} - } -} diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs deleted file mode 100644 index f98eec5a..00000000 --- a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs +++ /dev/null @@ -1,28 +0,0 @@ -// ISymUnmanagedDocumentWriter.cs -// -// Author: -// Juerg Billeter (j@bitron.ch) -// -// (C) 2008 Juerg Billeter -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Runtime.InteropServices; diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs deleted file mode 100644 index 9b14c210..00000000 --- a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs +++ /dev/null @@ -1,34 +0,0 @@ -// -// ISymUnmanagedWriter2.cs -// -// Author: -// Juerg Billeter (j@bitron.ch) -// -// (C) 2008 Juerg Billeter -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Diagnostics.SymbolStore; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.ComTypes; - -using Mono.Cecil.Cil; diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs deleted file mode 100644 index 7cf9c5d2..00000000 --- a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbHelper.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbHelper.cs deleted file mode 100644 index c6286355..00000000 --- a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbHelper.cs +++ /dev/null @@ -1,212 +0,0 @@ -// -// PdbHelper.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -using Mono.Cecil.Cil; - -namespace Mono.Cecil.Pdb -{ - - class PdbHelper - { - - - - public static string GetPdbFileName(string assemblyFileName) - { - return Path.ChangeExtension(assemblyFileName, ".pdb"); - } - } - - public class PdbReaderProvider : ISymbolReaderProvider - { - - public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName) - { - return new PdbReader(File.OpenRead(PdbHelper.GetPdbFileName(fileName))); - } - - public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream) - { - return new PdbReader(symbolStream); - } - } - - - public class GuidCompare : IEqualityComparer - { - - public bool Equals(Guid x, Guid y) - { - return x == y; - } - - public int GetHashCode(Guid obj) - { - return obj.GetHashCode(); - } - } - public class DocumentLanguageCompare : IEqualityComparer - { - - - public bool Equals(DocumentLanguage x, DocumentLanguage y) - { - return x == y; - } - - public int GetHashCode(DocumentLanguage obj) - { - return obj.GetHashCode(); - } - } - public class uintCompare : IEqualityComparer - { - public bool Equals(uint x, uint y) - { - return x == y; - } - - public int GetHashCode(uint obj) - { - return obj.GetHashCode(); - } - } - - static class GuidMapping - { - - static readonly Dictionary guid_language = new Dictionary(new GuidCompare()); - static readonly Dictionary language_guid = new Dictionary(new DocumentLanguageCompare()); - - 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(Guid guid) - { - if (guid == type_text) - return DocumentType.Text; - - return DocumentType.Other; - } - - public static Guid ToGuid(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(Guid guid) - { - if (guid == hash_md5) - return DocumentHashAlgorithm.MD5; - - if (guid == hash_sha1) - return DocumentHashAlgorithm.SHA1; - - return DocumentHashAlgorithm.None; - } - - public static Guid ToGuid(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(Guid guid) - { - DocumentLanguage language; - if (!guid_language.TryGetValue(guid, out language)) - return DocumentLanguage.Other; - - return language; - } - - public static Guid ToGuid(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(Guid guid) - { - if (guid == vendor_ms) - return DocumentLanguageVendor.Microsoft; - - return DocumentLanguageVendor.Other; - } - - public static Guid ToGuid(DocumentLanguageVendor vendor) - { - if (vendor == DocumentLanguageVendor.Microsoft) - return vendor_ms; - - return new Guid(); - } - } -} - diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbReader.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbReader.cs deleted file mode 100644 index 1449e1da..00000000 --- a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbReader.cs +++ /dev/null @@ -1,286 +0,0 @@ -// -// PdbReader.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.IO; - -using Microsoft.Cci.Pdb; - -using Mono.Cecil.Cil; - -namespace Mono.Cecil.Pdb -{ - - public class PdbReader : ISymbolReader - { - - int age; - Guid guid; - - readonly Stream pdb_file; - readonly Dictionary documents = new Dictionary(); - readonly Dictionary functions = new Dictionary(new uintCompare()); - - internal PdbReader(Stream file) - { - this.pdb_file = file; - } - - /* - uint Magic = 0x53445352; - Guid Signature; - uint Age; - string FileName; - */ - - public bool ProcessDebugHeader(ImageDebugDirectory directory, byte[] header) - { - if (header.Length < 24) - return false; - - var magic = ReadInt32(header, 0); - if (magic != 0x53445352) - return false; - - var guid_bytes = new byte[16]; - Buffer.BlockCopy(header, 4, guid_bytes, 0, 16); - - this.guid = new Guid(guid_bytes); - this.age = ReadInt32(header, 20); - - return PopulateFunctions(); - } - - static int ReadInt32(byte[] bytes, int start) - { - return (bytes[start] - | (bytes[start + 1] << 8) - | (bytes[start + 2] << 16) - | (bytes[start + 3] << 24)); - } - - bool PopulateFunctions() - { - using (pdb_file) - { - int age; - Guid guid; - var funcs = PdbFile.LoadFunctions(pdb_file, true, out age, out guid); - - if (this.age != 0 && this.guid != guid) - return false; - - foreach (PdbFunction function in funcs) - functions.Add(function.token, function); - } - - return true; - } - - public void Read(MethodBody body, InstructionMapper mapper) - { - var method_token = body.Method.MetadataToken; - - PdbFunction function; - if (!functions.TryGetValue(method_token.ToUInt32(), out function)) - return; - - ReadSequencePoints(function, mapper); - ReadScopeAndLocals(function.scopes, null, body, mapper); - } - - static void ReadScopeAndLocals(PdbScope[] scopes, Scope parent, MethodBody body, InstructionMapper mapper) - { - foreach (PdbScope scope in scopes) - ReadScopeAndLocals(scope, parent, body, mapper); - - CreateRootScope(body); - } - - static void CreateRootScope(MethodBody body) - { - if (!body.HasVariables) - return; - - var instructions = body.Instructions; - - var root = new Scope(); - root.Start = instructions[0]; - root.End = instructions[instructions.Count - 1]; - - var variables = body.Variables; - for (int i = 0; i < variables.Count; i++) - root.Variables.Add(variables[i]); - - body.Scope = root; - } - - static void ReadScopeAndLocals(PdbScope scope, Scope parent, MethodBody body, InstructionMapper mapper) - { - //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); - - if (scope == null) - return; - - foreach (PdbSlot slot in scope.slots) - { - int index = (int)slot.slot; - if (index < 0 || index >= body.Variables.Count) - continue; - - VariableDefinition variable = body.Variables[index]; - variable.Name = slot.name; - - //s.Variables.Add (variable); - } - - ReadScopeAndLocals(scope.scopes, null /* s */, body, mapper); - } - - void ReadSequencePoints(PdbFunction function, InstructionMapper mapper) - { - if (function.lines == null) - return; - - foreach (PdbLines lines in function.lines) - ReadLines(lines, mapper); - } - - void ReadLines(PdbLines lines, InstructionMapper mapper) - { - var document = GetDocument(lines.file); - - foreach (var line in lines.lines) - ReadLine(line, document, mapper); - } - - static void ReadLine(PdbLine line, Document document, InstructionMapper mapper) - { - var instruction = mapper((int)line.offset); - if (instruction == null) - return; - - var sequence_point = new SequencePoint(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; - } - - Document GetDocument(PdbSource source) - { - string name = source.name; - Document document; - if (documents.TryGetValue(name, out document)) - return document; - - document = new Document(name) - { - Language = GuidMapping.ToLanguage(source.language), - LanguageVendor = GuidMapping.ToVendor(source.vendor), - Type = GuidMapping.ToType(source.doctype), - }; - documents.Add(name, document); - 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/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbWriter.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbWriter.cs deleted file mode 100644 index d11a8638..00000000 --- a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbWriter.cs +++ /dev/null @@ -1,34 +0,0 @@ -// -// PdbWriter.cs -// -// Author: -// Jb Evain (jbevain@gmail.com) -// -// Copyright (c) 2008 - 2011 Jb Evain -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Diagnostics.SymbolStore; - -using Mono.Cecil.Cil; -using Mono.Collections.Generic; diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs deleted file mode 100644 index db6cb437..00000000 --- a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// SymDocumentWriter.cs -// -// Author: -// Juerg Billeter (j@bitron.ch) -// -// (C) 2008 Juerg Billeter -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymWriter.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymWriter.cs deleted file mode 100644 index 306af962..00000000 --- a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymWriter.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// SymWriter.cs -// -// Author: -// Juerg Billeter (j@bitron.ch) -// -// (C) 2008 Juerg Billeter -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System; -using System.Collections.Generic; -using System.Diagnostics.SymbolStore; -using System.Runtime.InteropServices; - -using Mono.Cecil.Cil; -using Mono.Collections.Generic; - -