diff options
author | Jb Evain <jbevain@gmail.com> | 2007-10-04 13:10:28 +0400 |
---|---|---|
committer | Jb Evain <jbevain@gmail.com> | 2007-10-04 13:10:28 +0400 |
commit | c7bed307ff24d060542e69d838b019fc5022d137 (patch) | |
tree | e0f0dd64cb5bb4e704ce111b47412f8ef636a08f | |
parent | 2cf44b169034847e50ad95dc494f2fa3f6674910 (diff) | |
parent | bdc9dc4ff3947c28191156bde73665fa99cd82a3 (diff) |
tag 0.6
svn path=/tags/cecil-0.6/; revision=86859
10 files changed, 530 insertions, 0 deletions
diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/AUTHORS b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/AUTHORS new file mode 100644 index 00000000000..fcfe3126c23 --- /dev/null +++ b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/AUTHORS @@ -0,0 +1 @@ +Jb Evain <jbevain@novell.com> diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/ChangeLog b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/ChangeLog new file mode 100644 index 00000000000..c38c1db1abb --- /dev/null +++ b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/ChangeLog @@ -0,0 +1,23 @@ +2007-08-28 Jb Evain <jbevain@novell.com> + + * Mono.Cecil.Mdb/MdbWriter.cs: + Rewrite variables infos. + +2007-08-27 Jb Evain <jbevain@novell.com> + + * Mono.Cecil.Mdb/MdbWriter.cs: + Rewrite using the direct mdb api. + +2007-02-21 Jb Evain <jb@nurv.fr> + + * Start working on local var debug infos emitting. + +2006-09-24 Jb Evain <jbevain@gmail.com> + + * start some work on the reader. + +2006-09-19 Jb Evain <jbevain@gmail.com> + + * first checkin in SVN: + This is the assembly to support reading and writing + from Mono's mdb symbol store. diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Makefile b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Makefile new file mode 100644 index 00000000000..b8f72bd0cda --- /dev/null +++ b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Makefile @@ -0,0 +1,12 @@ +thisdir = class/Mono.Cecil.Mdb +include ../../build/rules.make + +LIBRARY = Mono.Cecil.Mdb.dll +LIBRARY_SNK = ../mono.snk +LIBRARY_PACKAGE = none + +LIB_MCS_FLAGS = /r:$(corlib) /r:Mono.Cecil.dll /d:CECIL -keyfile:$(LIBRARY_SNK) + +NO_TEST = yes + +include ../../build/library.make diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj new file mode 100644 index 00000000000..3f743608cfe --- /dev/null +++ b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj @@ -0,0 +1,61 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{C5D12431-9C20-4789-8FEC-46094B0F81B5}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>Mono.Cecil.Mdb</RootNamespace> + <AssemblyName>Mono.Cecil.Mdb</AssemblyName> + <StartupObject> + </StartupObject> + <SignAssembly>true</SignAssembly> + <AssemblyOriginatorKeyFile>..\..\mcs\class\mono.snk</AssemblyOriginatorKeyFile> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> + <ItemGroup> + <Compile Include="Mono.Cecil.Mdb\AssemblyInfo.cs" /> + <Compile Include="Mono.Cecil.Mdb\MdbFactory.cs" /> + <Compile Include="Mono.Cecil.Mdb\MdbReader.cs" /> + <Compile Include="Mono.Cecil.Mdb\MdbWriter.cs" /> + <Compile Include="Mono.CompilerServices.SymbolWriter\MonoSymbolFile.cs" /> + <Compile Include="Mono.CompilerServices.SymbolWriter\MonoSymbolTable.cs" /> + <Compile Include="Mono.CompilerServices.SymbolWriter\MonoSymbolWriter.cs" /> + <Compile Include="Mono.CompilerServices.SymbolWriter\SymbolWriterImpl.cs" /> + </ItemGroup> + <ItemGroup> + <Reference Include="System" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\mcs\class\Mono.Cecil\Mono.Cecil.csproj"> + <Project>{D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}</Project> + <Name>Mono.Cecil</Name> + </ProjectReference> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb.dll.sources b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb.dll.sources new file mode 100644 index 00000000000..092a51e9432 --- /dev/null +++ b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb.dll.sources @@ -0,0 +1,8 @@ +./Mono.Cecil.Mdb/AssemblyInfo.cs +./Mono.Cecil.Mdb/MdbFactory.cs +./Mono.Cecil.Mdb/MdbReader.cs +./Mono.Cecil.Mdb/MdbWriter.cs +../Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs +../Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs +../Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs +../Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/AssemblyInfo.cs b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/AssemblyInfo.cs new file mode 100644 index 00000000000..5debf10fff0 --- /dev/null +++ b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/AssemblyInfo.cs @@ -0,0 +1,43 @@ +// +// AssemblyInfo.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2006 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.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle ("Mono.Cecil.Mdb")] +[assembly: AssemblyDescription ("Support for the mdb symbols store in Cecil")] +[assembly: AssemblyConfiguration ("")] +[assembly: AssemblyProduct ("Mono.Cecil")] +[assembly: AssemblyCopyright ("(C) 2006, Jb Evain")] +[assembly: AssemblyCulture ("")] + +[assembly: CLSCompliant (false)] +[assembly: ComVisible (false)] + +[assembly: AssemblyVersion ("0.2.0.0")] diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbFactory.cs b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbFactory.cs new file mode 100644 index 00000000000..0d1944ccf33 --- /dev/null +++ b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbFactory.cs @@ -0,0 +1,49 @@ +// +// MdbFactory.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2006 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.Mdb { + + using System; + + using Mono.Cecil.Cil; + + using Mono.CompilerServices.SymbolWriter; + + public class MdbFactory : ISymbolStoreFactory { + + public ISymbolReader CreateReader (ModuleDefinition module, string assembly) + { + return new MdbReader (MonoSymbolFile.ReadSymbolFile (module.Assembly, assembly)); + } + + public ISymbolWriter CreateWriter (ModuleDefinition module, string assembly) + { + return new MdbWriter (module.Mvid, assembly); + } + } +} diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbReader.cs b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbReader.cs new file mode 100644 index 00000000000..a40d44e973a --- /dev/null +++ b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbReader.cs @@ -0,0 +1,152 @@ +// +// MdbReader.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// (C) 2006 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.Mdb { + + using System.Collections; + + using Mono.Cecil.Cil; + + using Mono.CompilerServices.SymbolWriter; + + class MdbReader : ISymbolReader { + + MonoSymbolFile m_symFile; + Hashtable m_documents; + Hashtable m_scopes; + + public MdbReader (MonoSymbolFile symFile) + { + m_symFile = symFile; + m_documents = new Hashtable (); + m_scopes = new Hashtable (); + } + + Hashtable GetInstructions (MethodBody body) + { + Hashtable instructions = new Hashtable (body.Instructions.Count); + foreach (Instruction i in body.Instructions) + instructions.Add (i.Offset, i); + + return instructions; + } + + Instruction GetInstruction (MethodBody body, Hashtable instructions, int offset) + { + Instruction instr = (Instruction) instructions [offset]; + if (instr != null) + return instr; + + return body.Instructions.Outside; + } + + public void Read (MethodBody body) + { + MethodEntry entry = m_symFile.GetMethodByToken ((int) body.Method.MetadataToken.ToUInt ()); + if (entry == null) + return; + + Hashtable instructions = GetInstructions(body); + ReadScopes (entry, body, instructions); + ReadLineNumbers (entry, instructions); + ReadLocalVariables (entry, body); + } + + void ReadLocalVariables (MethodEntry entry, MethodBody body) + { + foreach (LocalVariableEntry loc in entry.Locals) { + Scope scope = m_scopes [loc.BlockIndex] as Scope; + if (scope == null) + continue; + + VariableDefinition var = body.Variables [loc.Index]; + var.Name = loc.Name; + scope.Variables.Add (var); + } + } + + void ReadLineNumbers (MethodEntry entry, Hashtable instructions) + { + foreach (LineNumberEntry line in entry.LineNumbers) { + Instruction instr = instructions [line.Offset] as Instruction; + if (instr == null) + continue; + + Document doc = GetDocument (entry.SourceFile); + instr.SequencePoint = new SequencePoint (doc); + instr.SequencePoint.StartLine = line.Row; + instr.SequencePoint.EndLine = line.Row; + } + } + + Document GetDocument (SourceFileEntry file) + { + Document doc = m_documents [file.FileName] as Document; + if (doc != null) + return doc; + + doc = new Document (file.FileName); + + m_documents [file.FileName] = doc; + return doc; + } + + void ReadScopes (MethodEntry entry, MethodBody body, Hashtable instructions) + { + foreach (LexicalBlockEntry scope in entry.LexicalBlocks) { + Scope s = new Scope (); + s.Start = GetInstruction (body, instructions, scope.StartOffset); + s.End = GetInstruction(body, instructions, scope.EndOffset); + m_scopes [scope.Index] = s; + + if (!AddScope (body, s)) + body.Scopes.Add (s); + } + } + + bool AddScope (IScopeProvider provider, Scope s) + { + foreach (Scope scope in provider.Scopes) { + if (AddScope (scope, s)) + return true; + + if (s.Start.Offset >= scope.Start.Offset && s.End.Offset <= scope.End.Offset) { + scope.Scopes.Add (s); + return true; + } + } + + return false; + } + + public void Dispose () + { + m_symFile.Dispose (); + } + } +} diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbWriter.cs b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbWriter.cs new file mode 100644 index 00000000000..eb302a8ac4d --- /dev/null +++ b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/Mono.Cecil.Mdb/MdbWriter.cs @@ -0,0 +1,179 @@ +// +// MdbWriter.cs +// +// Author: +// Jb Evain (jbevain@novell.com) +// +// (C) 2007 Novell, Inc. +// +// 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. +// + +// Inspired by the pdb2mdb tool written by Robert Jordan, thanks Robert! + +namespace Mono.Cecil.Mdb { + + using System; + using System.Collections; + + using Mono.CompilerServices.SymbolWriter; + + using Mono.Cecil; + using Mono.Cecil.Cil; + + class MdbWriter : ISymbolWriter { + + Guid m_mvid; + MonoSymbolWriter m_writer; + + Hashtable m_documents; + + public MdbWriter (Guid mvid, string assembly) + { + m_mvid = mvid; + m_writer = new MonoSymbolWriter (assembly); + m_documents = new Hashtable (); + } + + static Instruction [] GetInstructions (MethodBody body) + { + ArrayList list = new ArrayList (); + foreach (Instruction instruction in body.Instructions) + if (instruction.SequencePoint != null) + list.Add (instruction); + + return list.ToArray (typeof (Instruction)) as Instruction []; + } + + SourceFile GetSourceFile (Document document) + { + string url = document.Url; + SourceFile file = m_documents [url] as SourceFile; + if (file != null) + return file; + + file = new SourceFile (m_writer.DefineDocument (url)); + m_documents [url] = file; + return file; + } + + void Populate (Instruction [] instructions, int [] offsets, + int [] startRows, int [] startCols, int [] endRows, int [] endCols, + out SourceFile file) + { + SourceFile document = null; + + for (int i = 0; i < instructions.Length; i++) { + Instruction instr = (Instruction) instructions [i]; + offsets [i] = instr.Offset; + + if (document == null) + document = GetSourceFile (instr.SequencePoint.Document); + + startRows [i] = instr.SequencePoint.StartLine; + startCols [i] = instr.SequencePoint.StartColumn; + endRows [i] = instr.SequencePoint.EndLine; + endCols [i] = instr.SequencePoint.EndColumn; + } + + file = document; + } + + public void Write (MethodBody body, byte [][] variables) + { + SourceMethod meth = new SourceMethod (body.Method); + + SourceFile file; + + Instruction [] instructions = GetInstructions (body); + int length = instructions.Length; + if (length == 0) + return; + + int [] offsets = new int [length]; + int [] startRows = new int [length]; + int [] startCols = new int [length]; + int [] endRows = new int [length]; + int [] endCols = new int [length]; + + Populate (instructions, offsets, startRows, startCols, endRows, endCols, out file); + + m_writer.OpenMethod (file, meth, + startRows [0], startCols [0], + endRows [length - 1], endCols [length - 1]); + + for (int i = 0; i < length; i++) + m_writer.MarkSequencePoint (offsets [i], startRows [i], startCols [i]); + + MarkVariables (body, variables); + + m_writer.CloseMethod (); + } + + void MarkVariables (MethodBody body, byte [][] variables) + { + for (int i = 0; i < body.Variables.Count; i++) { + VariableDefinition var = body.Variables [i]; + m_writer.DefineLocalVariable (i, var.Name, variables [i]); + } + } + + public void Dispose () + { + m_writer.WriteSymbolFile (m_mvid); + } + + class SourceFile : ISourceFile { + + SourceFileEntry m_entry; + + public SourceFileEntry Entry { + get { return m_entry; } + } + + public SourceFile (SourceFileEntry entry) + { + m_entry = entry; + } + } + + class SourceMethod : ISourceMethod { + + MethodDefinition m_method; + + public string Name { + get { return m_method.Name; } + } + + public int NamespaceID { + get { return 0; } + } + + public int Token { + get { return (int) m_method.MetadataToken.ToUInt (); } + } + + public SourceMethod (MethodDefinition method) + { + m_method = method; + } + } + } +} diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/README b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/README new file mode 100644 index 00000000000..ef817611010 --- /dev/null +++ b/mcs/class/Mono.Cecil/Mono.Cecil.Mdb/README @@ -0,0 +1,2 @@ +Mono.Cecil.Mdb is an internal assembly used by Mono.Cecil to +read and write the Mono Debugging Symbols file format. |