Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJb Evain <jbevain@gmail.com>2007-10-04 13:10:48 +0400
committerJb Evain <jbevain@gmail.com>2007-10-04 13:10:48 +0400
commite2b6cbaf2793354590a7fe542afe811aa03d0a2e (patch)
tree7ef9e18ed44f93890257853faf0a2d58d68ab895
parentc7bed307ff24d060542e69d838b019fc5022d137 (diff)
tag 0.6cecil-0.6
svn path=/tags/cecil-0.6/; revision=86860
-rw-r--r--mcs/class/Mono.Cecil/Mono.Cecil.Pdb/ChangeLog31
-rw-r--r--mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj61
-rw-r--r--mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/AssemblyInfo.cs43
-rw-r--r--mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/IMetadataDispenser.cs56
-rw-r--r--mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/IMetadataImport.cs43
-rw-r--r--mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbFactory.cs46
-rw-r--r--mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbHelper.cs130
-rw-r--r--mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbReader.cs148
-rw-r--r--mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbWriter.cs202
-rw-r--r--mcs/class/Mono.Cecil/Mono.Cecil.Pdb/default.build49
10 files changed, 809 insertions, 0 deletions
diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/ChangeLog b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/ChangeLog
new file mode 100644
index 00000000000..6cefb798b89
--- /dev/null
+++ b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/ChangeLog
@@ -0,0 +1,31 @@
+2007-02-21 Jb Evain <jb@nurv.fr>
+
+ * Start working on local var debug infos emitting.
+
+2007-02-21 Jb Evain <jbevain@gmail.com>
+
+ * Mono.Cecil.Pdb/PdbReader.cs
+ Mono.Cecil.Pdb/PdbHelper.cs
+ Mono.Cecil.Pdb/IMetaDataDispenser.cs:
+ Refactor patches from:
+ Sverre Boschman <s.r.boschman@iego-development.nl>
+
+ - Force the release of the lock on the pdb on reading
+ - Implement the ability to read a pdb in memory
+
+2006-09-24 Jb Evain <jbevain@gmail.com>
+
+ * Handle the fact that a scope end points outside the cil stream.
+
+2006-09-20 Jb Evain <jbevain@gmail.com>
+
+ * implement somes bits of the writing stuff.
+
+2006-09-19 Jb Evain <jbevain@gmail.com>
+
+ * first checkin in SVN:
+ This is the assembly to support reading and writing
+ from Microsoft's pdb symbols store.
+
+ It will only work on Windows until Microsoft release
+ the spec for the pdb files.
diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj
new file mode 100644
index 00000000000..738160c65fa
--- /dev/null
+++ b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb.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>{4FEBBB25-D5C0-48F0-A822-2E0D6F3D777E}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Mono.Cecil.Pdb</RootNamespace>
+ <AssemblyName>Mono.Cecil.Pdb</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.Pdb\AssemblyInfo.cs" />
+ <Compile Include="Mono.Cecil.Pdb\IMetadataDispenser.cs" />
+ <Compile Include="Mono.Cecil.Pdb\IMetadataImport.cs" />
+ <Compile Include="Mono.Cecil.Pdb\PdbFactory.cs" />
+ <Compile Include="Mono.Cecil.Pdb\PdbReader.cs" />
+ <Compile Include="Mono.Cecil.Pdb\PdbWriter.cs" />
+ <Compile Include="Mono.Cecil.Pdb\PdbHelper.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Reference Include="ISymWrapper" />
+ <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.Pdb/Mono.Cecil.Pdb/AssemblyInfo.cs b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/AssemblyInfo.cs
new file mode 100644
index 00000000000..5bdef131cca
--- /dev/null
+++ b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/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.Pdb")]
+[assembly: AssemblyDescription ("Support for the pdb 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.Pdb/Mono.Cecil.Pdb/IMetadataDispenser.cs b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/IMetadataDispenser.cs
new file mode 100644
index 00000000000..7f41d0e3520
--- /dev/null
+++ b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/IMetadataDispenser.cs
@@ -0,0 +1,56 @@
+//
+// IMetadataImport.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.
+//
+
+// from: http://blogs.msdn.com/jmstall/articles/sample_pdb2xml.aspx
+
+namespace Mono.Cecil.Pdb {
+
+ using System;
+ using System.Runtime.InteropServices;
+
+ [Guid ("809c652e-7396-11d2-9771-00a0c9b4d50c")]
+ [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
+ [ComVisible (true)]
+ interface IMetaDataDispenser {
+
+ void DefineScope_Placeholder();
+
+ void OpenScope (
+ [In, MarshalAs (UnmanagedType.LPWStr)] string szScope,
+ [In] int dwOpenFlags,
+ [In] ref Guid riid,
+ [Out, MarshalAs (UnmanagedType.IUnknown)] out object punk);
+
+ void OpenScopeOnMemory (
+ [In] IntPtr pData,
+ [In] uint cbData,
+ [In] uint dwOpenFlags,
+ [In] ref Guid riid,
+ [Out, MarshalAs (UnmanagedType.Interface)] out object punk);
+ }
+}
diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/IMetadataImport.cs b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/IMetadataImport.cs
new file mode 100644
index 00000000000..71e8d622750
--- /dev/null
+++ b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/IMetadataImport.cs
@@ -0,0 +1,43 @@
+//
+// IMetadataImport.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.
+//
+
+// from: http://blogs.msdn.com/jmstall/articles/sample_pdb2xml.aspx
+
+namespace Mono.Cecil.Pdb {
+
+ using System;
+ using System.Runtime.InteropServices;
+
+ [Guid ("7DAC8207-D3AE-4c75-9B67-92801A497D44")]
+ [InterfaceType (ComInterfaceType.InterfaceIsIUnknown)]
+ [ComVisible (true)]
+ [CLSCompliant (true)]
+ public interface IMetadataImport {
+ void Placeholder();
+ }
+}
diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbFactory.cs b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbFactory.cs
new file mode 100644
index 00000000000..99a4f446d82
--- /dev/null
+++ b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbFactory.cs
@@ -0,0 +1,46 @@
+//
+// PdbFactory.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.Pdb {
+
+ using Mono.Cecil.Cil;
+
+ public class PdbFactory : ISymbolStoreFactory {
+
+ public ISymbolReader CreateReader (ModuleDefinition module, string assembly)
+ {
+ return new PdbReader (PdbHelper.CreateReader (assembly));
+ }
+
+ public ISymbolWriter CreateWriter (ModuleDefinition module, string assembly)
+ {
+ string pdb = string.Concat(assembly.Substring(0, assembly.LastIndexOf(".")), ".pdb");
+ return new PdbWriter (PdbHelper.CreateWriter (assembly, pdb), module, pdb);
+ }
+ }
+}
diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbHelper.cs b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbHelper.cs
new file mode 100644
index 00000000000..79a15d71e6f
--- /dev/null
+++ b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbHelper.cs
@@ -0,0 +1,130 @@
+//
+// PdbHelper.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.
+//
+
+// from: http://blogs.msdn.com/jmstall/articles/sample_pdb2xml.aspx
+
+namespace Mono.Cecil.Pdb {
+
+ using System;
+ using System.Diagnostics.SymbolStore;
+ using System.IO;
+ using System.Runtime.InteropServices;
+
+ internal class PdbHelper {
+
+ [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_dispenserClassID = new Guid (0xe5cb7a31, 0x7512, 0x11d2, 0x89, 0xce, 0x00, 0x80, 0xc7, 0x92, 0xe5, 0xd8);
+ static Guid s_dispenserIID = new Guid (0x809c652e, 0x7396, 0x11d2, 0x97, 0x71, 0x00, 0xa0, 0xc9, 0xb4, 0xd5, 0x0c);
+ static Guid s_importerIID = new Guid (0x7dac8207, 0xd3ae, 0x4c75, 0x9b, 0x67, 0x92, 0x80, 0x1a, 0x49, 0x7d, 0x44);
+
+ public static ISymbolReader CreateReader (string filename)
+ {
+ SymBinder binder;
+ object objImporter;
+
+ IMetaDataDispenser dispenser = InstantiateDispenser (out binder);
+ dispenser.OpenScope (filename, 0, ref s_importerIID, out objImporter);
+
+ return InstantiateReader (binder, filename, objImporter);
+ }
+
+ public static ISymbolReader CreateReader (string filename, byte [] binaryFile)
+ {
+ SymBinder binder;
+ object objImporter;
+
+ IntPtr filePtr = Marshal.AllocHGlobal (binaryFile.Length);
+ Marshal.Copy (binaryFile, 0, filePtr, binaryFile.Length);
+
+ IMetaDataDispenser dispenser = InstantiateDispenser (out binder);
+ dispenser.OpenScopeOnMemory (filePtr, (uint) binaryFile.Length, 0, ref s_importerIID, out objImporter);
+
+ return InstantiateReader (binder, filename, objImporter);
+ }
+
+ static IMetaDataDispenser InstantiateDispenser (out SymBinder binder)
+ {
+ binder = new SymBinder ();
+ object dispenser;
+ CoCreateInstance (ref s_dispenserClassID, null, 1, ref s_dispenserIID, out dispenser);
+ return (IMetaDataDispenser) dispenser;
+ }
+
+ static ISymbolReader InstantiateReader (SymBinder binder, string filename, object objImporter)
+ {
+ IntPtr importerPtr = IntPtr.Zero;
+ ISymbolReader reader;
+ try {
+ importerPtr = Marshal.GetComInterfaceForObject (objImporter, typeof (IMetadataImport));
+
+ reader = binder.GetReader (importerPtr, filename, null);
+ } finally {
+ if (importerPtr != IntPtr.Zero)
+ Marshal.Release (importerPtr);
+ }
+
+ return reader;
+ }
+
+ public static ISymbolWriter CreateWriter (string assembly, string pdb)
+ {
+ SymWriter writer = new SymWriter (false);
+
+ object objDispenser, objImporter;
+ CoCreateInstance (ref s_dispenserClassID, null, 1, ref s_dispenserIID, out objDispenser);
+
+ IMetaDataDispenser dispenser = (IMetaDataDispenser) objDispenser;
+ dispenser.OpenScope (assembly, 1, ref s_importerIID, out objImporter);
+
+ IntPtr importerPtr = Marshal.GetComInterfaceForObject (objImporter, typeof (IMetadataImport));
+
+ try {
+ if (File.Exists (pdb))
+ File.Delete (pdb);
+
+ writer.Initialize (importerPtr, pdb, false);
+ } finally {
+ if (importerPtr != IntPtr.Zero) {
+ Marshal.Release (importerPtr);
+ Marshal.ReleaseComObject (objDispenser);
+ Marshal.ReleaseComObject (objImporter);
+ Marshal.ReleaseComObject (dispenser);
+ }
+ }
+
+ return writer;
+ }
+ }
+}
diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbReader.cs b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbReader.cs
new file mode 100644
index 00000000000..43ef718df81
--- /dev/null
+++ b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbReader.cs
@@ -0,0 +1,148 @@
+//
+// PdbReader.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.Pdb {
+
+ using System;
+ using System.Collections;
+ using System.Diagnostics.SymbolStore;
+ using System.Runtime.InteropServices;
+
+ public class PdbReader : Cil.ISymbolReader {
+
+ ISymbolReader m_reader;
+
+ Hashtable m_documents;
+
+ internal PdbReader (ISymbolReader reader)
+ {
+ m_reader = reader;
+ m_documents = new Hashtable ();
+ }
+
+ public void Read (Cil.MethodBody body)
+ {
+ try {
+ ISymbolMethod method = m_reader.GetMethod (new SymbolToken ((int) body.Method.MetadataToken.ToUInt ()));
+ Hashtable instructions = GetInstructions (body);
+
+ ReadSequencePoints (method, instructions);
+ ReadScopeAndLocals (method.RootScope, null, body, instructions);
+ } catch (COMException) {}
+ }
+
+ static Hashtable GetInstructions (Cil.MethodBody body)
+ {
+ Hashtable instructions = new Hashtable (body.Instructions.Count);
+ foreach (Cil.Instruction i in body.Instructions)
+ instructions.Add (i.Offset, i);
+
+ return instructions;
+ }
+
+ static Cil.Instruction GetInstruction (Cil.MethodBody body, Hashtable instructions, int offset)
+ {
+ Cil.Instruction instr = (Cil.Instruction) instructions [offset];
+ if (instr != null)
+ return instr;
+
+ return body.Instructions.Outside;
+ }
+
+ static void ReadScopeAndLocals (ISymbolScope scope, Cil.Scope parent, Cil.MethodBody body, Hashtable instructions)
+ {
+ Cil.Scope s = new Cil.Scope ();
+ s.Start = GetInstruction (body, instructions, scope.StartOffset);
+ s.End = GetInstruction (body, instructions, scope.EndOffset);
+
+ if (parent != null)
+ parent.Scopes.Add (s);
+ else
+ body.Scopes.Add (s);
+
+ foreach (ISymbolVariable local in scope.GetLocals ()) {
+ Cil.VariableDefinition variable = body.Variables [local.AddressField1];
+ variable.Name = local.Name;
+
+ s.Variables.Add (variable);
+ }
+
+ foreach (ISymbolScope child in scope.GetChildren ())
+ ReadScopeAndLocals (child, s, body, instructions);
+ }
+
+ void ReadSequencePoints(ISymbolMethod method, Hashtable instructions)
+ {
+ int count = method.SequencePointCount;
+ int [] offsets = new int [count];
+ ISymbolDocument [] docs = new ISymbolDocument [count];
+ int [] startColumn = new int [count];
+ int [] endColumn = new int [count];
+ int [] startRow = new int [count];
+ int [] endRow = new int [count];
+ method.GetSequencePoints (offsets, docs, startRow, startColumn, endRow, endColumn);
+
+ for (int i = 0; i < offsets.Length; i++) {
+ Cil.Instruction instr = (Cil.Instruction) instructions [offsets [i]];
+
+ Cil.SequencePoint sp = new Cil.SequencePoint (GetDocument (docs [i]));
+ sp.StartLine = startRow [i];
+ sp.StartColumn = startColumn [i];
+ sp.EndLine = endRow [i];
+ sp.EndColumn = endColumn [i];
+
+ instr.SequencePoint = sp;
+ }
+ }
+
+ Cil.Document GetDocument (ISymbolDocument document)
+ {
+ Cil.Document doc = m_documents [document.URL] as Cil.Document;
+ if (doc != null)
+ return doc;
+
+ doc = new Cil.Document (document.URL);
+ doc.Type = (Cil.DocumentType) Cil.GuidAttribute.GetValueFromGuid (
+ document.DocumentType, typeof (Cil.DocumentType));
+ doc.Language = (Cil.DocumentLanguage) Cil.GuidAttribute.GetValueFromGuid (
+ document.Language, typeof (Cil.DocumentLanguage));
+ doc.LanguageVendor = (Cil.DocumentLanguageVendor) Cil.GuidAttribute.GetValueFromGuid (
+ document.LanguageVendor, typeof (Cil.DocumentLanguageVendor));
+
+ m_documents [doc.Url] = doc;
+ return doc;
+ }
+
+ public void Dispose ()
+ {
+ m_reader = null;
+ // force the release of the pdb lock
+ GC.Collect ();
+ }
+ }
+}
diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbWriter.cs b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbWriter.cs
new file mode 100644
index 00000000000..881a04d2c1e
--- /dev/null
+++ b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/Mono.Cecil.Pdb/PdbWriter.cs
@@ -0,0 +1,202 @@
+//
+// PdbWriter.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 Mono.Cecil.Cil;
+
+namespace Mono.Cecil.Pdb {
+
+ using System;
+ using System.Collections;
+ using System.Diagnostics.SymbolStore;
+ using System.IO;
+
+ public class PdbWriter : Cil.ISymbolWriter {
+
+ ModuleDefinition m_module;
+ ISymbolWriter m_writer;
+ Hashtable m_documents;
+ string m_pdb;
+
+ internal PdbWriter (ISymbolWriter writer, ModuleDefinition module, string pdb)
+ {
+ m_writer = writer;
+ m_module = module;
+ m_documents = new Hashtable ();
+ m_pdb = pdb;
+ }
+
+ public void Write (MethodBody body, byte [][] variables)
+ {
+ CreateDocuments (body);
+ m_writer.OpenMethod (new SymbolToken ((int) body.Method.MetadataToken.ToUInt ()));
+ CreateScopes (body, body.Scopes, variables);
+ m_writer.CloseMethod ();
+ }
+
+ void CreateScopes (MethodBody body, ScopeCollection scopes, byte [][] variables)
+ {
+ foreach (Scope s in scopes) {
+ int startOffset = s.Start.Offset;
+ int endOffset = s.End == body.Instructions.Outside ?
+ body.Instructions[body.Instructions.Count - 1].Offset + 1 :
+ s.End.Offset;
+
+ m_writer.OpenScope (startOffset);
+ m_writer.UsingNamespace (body.Method.DeclaringType.Namespace);
+ m_writer.OpenNamespace (body.Method.DeclaringType.Namespace);
+
+ int start = body.Instructions.IndexOf (s.Start);
+ int end = s.End == body.Instructions.Outside ?
+ body.Instructions.Count - 1 :
+ body.Instructions.IndexOf (s.End);
+
+ ArrayList instructions = new ArrayList();
+ for (int i = start; i <= end; i++)
+ if (body.Instructions [i].SequencePoint != null)
+ instructions.Add (body.Instructions [i]);
+
+ Document doc = null;
+
+ int [] offsets = new int [instructions.Count];
+ int [] startRows = new int [instructions.Count];
+ int [] startCols = new int [instructions.Count];
+ int [] endRows = new int [instructions.Count];
+ int [] endCols = new int [instructions.Count];
+
+ for (int i = 0; i < instructions.Count; i++) {
+ Instruction instr = (Instruction) instructions [i];
+ offsets [i] = instr.Offset;
+
+ if (doc == null)
+ doc = instr.SequencePoint.Document;
+
+ startRows [i] = instr.SequencePoint.StartLine;
+ startCols [i] = instr.SequencePoint.StartColumn;
+ endRows [i] = instr.SequencePoint.EndLine;
+ endCols [i] = instr.SequencePoint.EndColumn;
+ }
+
+ m_writer.DefineSequencePoints (GetDocument (doc),
+ offsets, startRows, startCols, endRows, endCols);
+
+ CreateLocalVariable (s, startOffset, endOffset, variables);
+
+ CreateScopes (body, s.Scopes, variables);
+ m_writer.CloseNamespace ();
+
+ m_writer.CloseScope (endOffset);
+ }
+ }
+
+ void CreateLocalVariable (IVariableDefinitionProvider provider, int startOffset, int endOffset, byte [][] variables)
+ {
+ for (int i = 0; i < provider.Variables.Count; i++) {
+ VariableDefinition var = provider.Variables [i];
+ m_writer.DefineLocalVariable (
+ var.Name,
+ 0,
+ variables [i],
+ SymAddressKind.ILOffset,
+ i,
+ 0,
+ 0,
+ startOffset,
+ endOffset);
+ }
+ }
+
+ void CreateDocuments (MethodBody body)
+ {
+ foreach (Instruction instr in body.Instructions) {
+ if (instr.SequencePoint == null)
+ continue;
+
+ GetDocument (instr.SequencePoint.Document);
+ }
+ }
+
+ ISymbolDocumentWriter GetDocument (Document document)
+ {
+ if (document == null)
+ return null;
+
+ ISymbolDocumentWriter docWriter = m_documents [document.Url] as ISymbolDocumentWriter;
+ if (docWriter != null)
+ return docWriter;
+
+ docWriter = m_writer.DefineDocument (
+ document.Url,
+ GuidAttribute.GetGuidFromValue ((int) document.Language, typeof (DocumentLanguage)),
+ GuidAttribute.GetGuidFromValue ((int) document.LanguageVendor, typeof (DocumentLanguageVendor)),
+ GuidAttribute.GetGuidFromValue ((int) document.Type, typeof (DocumentType)));
+
+ m_documents [document.Url] = docWriter;
+ return docWriter;
+ }
+
+ public void Dispose ()
+ {
+ m_writer.Close ();
+ Patch ();
+ }
+
+ void Patch ()
+ {
+ FileStream fs = new FileStream (m_pdb, FileMode.Open, FileAccess.ReadWrite);
+ uint age = m_module.Image.DebugHeader.Age;
+ Guid g = m_module.Image.DebugHeader.Signature;
+
+ BinaryReader reader = new BinaryReader (fs);
+ reader.BaseStream.Position = 32;
+
+ uint pageSize = reader.ReadUInt32 ();
+ reader.BaseStream.Position += 4;
+
+ uint pageCount = reader.ReadUInt32 ();
+ reader.BaseStream.Position += pageSize - 44;
+
+ uint magic = 0x1312e94;
+ int page = 0;
+ for (int i = 1; i < pageCount; i++) {
+ if (magic == reader.ReadUInt32 ()) {
+ page = i;
+ break;
+ }
+ reader.BaseStream.Position += pageSize - 4;
+ }
+
+ BinaryWriter writer = new BinaryWriter (fs);
+ writer.BaseStream.Position = page * pageSize + 8;
+
+ writer.Write (age);
+ writer.Write (g.ToByteArray ());
+
+ fs.Close ();
+ }
+ }
+}
diff --git a/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/default.build b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/default.build
new file mode 100644
index 00000000000..94d81e83fbc
--- /dev/null
+++ b/mcs/class/Mono.Cecil/Mono.Cecil.Pdb/default.build
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<project name="Mono.Cecil.Pdb" default="build">
+
+ <!-- allow properties to be customized in external file" -->
+ <include buildfile="build.properties" if="${file::exists('build.properties')}" />
+
+ <property name="Mono.Cecil.dll" value="../../mcs/class/Mono.Cecil/bin/Mono.Cecil.dll" />
+ <property name="build.dir" value="bin" />
+ <property name="optimize" value="false" />
+ <property name="debug" value="true" />
+ <property name="keyfile" value="../../mcs/class/mono.snk" />
+ <property name="csc.defines" value="NO_DEFINE" />
+
+ <target name="release" depends="clean, set-release, build">
+ </target>
+
+ <target name="set-release">
+ <property name="optimize" value="true" />
+ <property name="debug" value="false" />
+ </target>
+
+ <target name="build" depends="init">
+ <csc
+ target="library"
+ output="${build.dir}/Mono.Cecil.Pdb.dll"
+ debug="${debug}"
+ optimize="${optimize}"
+ keyfile="${keyfile}"
+ define="${csc.defines}">
+ <sources basedir="Mono.Cecil.Pdb">
+ <include name="**/*.cs" />
+ </sources>
+ <references basedir="${build.dir}">
+ <include name="Mono.Cecil.dll" />
+ <include name="ISymWrapper.dll" />
+ </references>
+ </csc>
+ </target>
+
+ <target name="init">
+ <mkdir dir="${build.dir}" unless="${directory::exists(build.dir)}" />
+ <copy todir="${build.dir}" file="${Mono.Cecil.dll}" />
+ </target>
+
+ <target name="clean">
+ <delete dir="${build.dir}" if="${directory::exists(build.dir)}" />
+ </target>
+
+</project>