1 // 2 // Author: 3 // Juerg Billeter (j@bitron.ch) 4 // 5 // (C) 2008 Juerg Billeter 6 // 7 // Licensed under the MIT/X11 license. 8 // 9 10 using System; 11 using System.Runtime.InteropServices; 12 13 using Mono.Cecil.Cil; 14 using Mono.Collections.Generic; 15 16 #if !READ_ONLY 17 18 namespace Mono.Cecil.Pdb 19 { 20 internal class SymWriter 21 { 22 [DllImport("ole32.dll")] 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)23 static extern int CoCreateInstance ( 24 [In] ref Guid rclsid, 25 [In, MarshalAs (UnmanagedType.IUnknown)] object pUnkOuter, 26 [In] uint dwClsContext, 27 [In] ref Guid riid, 28 [Out, MarshalAs (UnmanagedType.Interface)] out object ppv); 29 30 static Guid s_symUnmangedWriterIID = new Guid("0b97726e-9e6d-4f05-9a26-424022093caa"); 31 static Guid s_CorSymWriter_SxS_ClassID = new Guid ("108296c1-281e-11d3-bd22-0000f80849bd"); 32 33 readonly ISymUnmanagedWriter2 m_writer; 34 readonly Collection<ISymUnmanagedDocumentWriter> documents; 35 SymWriter()36 public SymWriter () 37 { 38 object objWriter; 39 CoCreateInstance (ref s_CorSymWriter_SxS_ClassID, null, 1, ref s_symUnmangedWriterIID, out objWriter); 40 41 m_writer = (ISymUnmanagedWriter2) objWriter; 42 documents = new Collection<ISymUnmanagedDocumentWriter> (); 43 } 44 GetDebugInfo(out ImageDebugDirectory idd)45 public byte[] GetDebugInfo (out ImageDebugDirectory idd) 46 { 47 int size; 48 49 // get size of debug info 50 m_writer.GetDebugInfo (out idd, 0, out size, null); 51 52 byte[] debug_info = new byte[size]; 53 m_writer.GetDebugInfo (out idd, size, out size, debug_info); 54 55 return debug_info; 56 } 57 DefineLocalVariable2( string name, VariableAttributes attributes, int sigToken, int addr1, int addr2, int addr3, int startOffset, int endOffset)58 public void DefineLocalVariable2 ( 59 string name, 60 VariableAttributes attributes, 61 int sigToken, 62 int addr1, 63 int addr2, 64 int addr3, 65 int startOffset, 66 int endOffset) 67 { 68 m_writer.DefineLocalVariable2 (name, (int)attributes, sigToken, 1 /* ILOffset*/, addr1, addr2, addr3, startOffset, endOffset); 69 } 70 DefineConstant2(string name, object value, int sigToken)71 public void DefineConstant2 (string name, object value, int sigToken) 72 { 73 if (value == null) { 74 m_writer.DefineConstant2 (name, 0, sigToken); 75 return; 76 } 77 78 m_writer.DefineConstant2 (name, value, sigToken); 79 } 80 Close()81 public void Close () 82 { 83 m_writer.Close (); 84 Marshal.ReleaseComObject (m_writer); 85 86 foreach (var document in documents) 87 Marshal.ReleaseComObject (document); 88 } 89 CloseMethod()90 public void CloseMethod () 91 { 92 m_writer.CloseMethod (); 93 } 94 CloseNamespace()95 public void CloseNamespace () 96 { 97 m_writer.CloseNamespace (); 98 } 99 CloseScope(int endOffset)100 public void CloseScope (int endOffset) 101 { 102 m_writer.CloseScope (endOffset); 103 } 104 DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType)105 public SymDocumentWriter DefineDocument (string url, Guid language, Guid languageVendor, Guid documentType) 106 { 107 ISymUnmanagedDocumentWriter unmanagedDocumentWriter; 108 m_writer.DefineDocument (url, ref language, ref languageVendor, ref documentType, out unmanagedDocumentWriter); 109 110 documents.Add (unmanagedDocumentWriter); 111 return new SymDocumentWriter (unmanagedDocumentWriter); 112 } 113 DefineSequencePoints(SymDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns)114 public void DefineSequencePoints (SymDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) 115 { 116 m_writer.DefineSequencePoints (document.GetUnmanaged(), offsets.Length, offsets, lines, columns, endLines, endColumns); 117 } 118 Initialize(object emitter, string filename, bool fFullBuild)119 public void Initialize (object emitter, string filename, bool fFullBuild) 120 { 121 m_writer.Initialize (emitter, filename, null, fFullBuild); 122 } 123 SetUserEntryPoint(int methodToken)124 public void SetUserEntryPoint (int methodToken) 125 { 126 m_writer.SetUserEntryPoint (methodToken); 127 } 128 OpenMethod(int methodToken)129 public void OpenMethod (int methodToken) 130 { 131 m_writer.OpenMethod (methodToken); 132 } 133 OpenNamespace(string name)134 public void OpenNamespace (string name) 135 { 136 m_writer.OpenNamespace (name); 137 } 138 OpenScope(int startOffset)139 public int OpenScope (int startOffset) 140 { 141 int result; 142 m_writer.OpenScope (startOffset, out result); 143 return result; 144 } 145 UsingNamespace(string fullName)146 public void UsingNamespace (string fullName) 147 { 148 m_writer.UsingNamespace (fullName); 149 } 150 DefineCustomMetadata(string name, byte [] metadata)151 public void DefineCustomMetadata (string name, byte [] metadata) 152 { 153 var handle = GCHandle.Alloc (metadata, GCHandleType.Pinned); 154 m_writer.SetSymAttribute (0, name, (uint) metadata.Length, handle.AddrOfPinnedObject ()); 155 handle.Free (); 156 } 157 } 158 } 159 160 #endif 161