SymbolWriter.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. //
  2. // This code is the managed pdb writer interface for PERWAPI.
  3. // Written by John Gough, January 2008.
  4. // Copyright(c) 2007-2010 John Gough, and Queensland University of Technology
  5. //
  6. // NOTES:
  7. // Q: Where does this code come from?
  8. // A: At the heart of the code is some COM interop that accesses the
  9. // facilities of mscoree.dll. Unfortunately, the type library for
  10. // this component is incomplete, and does not cover the symbol store
  11. // functionality. There is some MIDL, and the C++ header files
  12. // cor.h and corsym.h. From here comes the guid values, for
  13. // example, and critically the order of the interface methods.
  14. // The managed interfaces, such as ISymbolReader, are defined in
  15. // [mscorlib]System.Diagnostics.SymbolStore.
  16. //
  17. // This file provides managed wrappers for the unmanaged interfaces.
  18. // These wrappers implement the managed interfaces.
  19. // Not all methods are implemented. Those that are not will throw
  20. // NotImplementedException.
  21. //
  22. // Some of the functionality currently not used by PERWAPI is left
  23. // unimplemented, and throws a NotImplementedException if called.
  24. //
  25. // THANKS:
  26. // Wayne Kelly, whose SimpleWriter, in C++ pointed the way.
  27. // Adam Nathan, whose ".NET and COM" tells you more than you want to know
  28. // Microsoft's Iron Python and MDBG samples answered remaining questions
  29. //
  30. using System;
  31. using System.Collections.Generic;
  32. using System.Text;
  33. using System.Runtime.InteropServices;
  34. using System.Runtime.InteropServices.ComTypes;
  35. using System.Diagnostics.SymbolStore;
  36. namespace QUT.Symbols {
  37. public class SymbolWriter {
  38. private ISymUnmanagedWriter2 writer;
  39. public SymbolWriter(string binaryFile, string pdbFile) {
  40. object dispenser = null;
  41. object pUnknown = null;
  42. IntPtr importer = IntPtr.Zero;
  43. object writer2 = null;
  44. try {
  45. OLE32.CoCreateInstance(ref XGuid.dispenserClassID, null, 1, ref XGuid.dispenserIID, out dispenser);
  46. ((IMetaDataDispenserSubset)dispenser).OpenScope(binaryFile, 0, ref XGuid.importerIID, out pUnknown);
  47. importer = Marshal.GetComInterfaceForObject(pUnknown, typeof(IMetadataImport));
  48. OLE32.CoCreateInstance(ref XGuid.symWriterClassID, null, 1, ref XGuid.symWriterIID, out writer2);
  49. writer = (ISymUnmanagedWriter2)writer2;
  50. writer.Initialize(importer, pdbFile, null, true);
  51. }
  52. catch (Exception x) {
  53. Console.WriteLine(x.Message);
  54. }
  55. finally {
  56. if (importer != IntPtr.Zero)
  57. Marshal.Release(importer);
  58. }
  59. }
  60. public object DefineDocument(string url, ref Guid language, ref Guid vendor, ref Guid docType) {
  61. ISymUnmanagedDocumentWriter docWriter;
  62. writer.DefineDocument(url, ref language, ref vendor, ref docType, out docWriter);
  63. return (object)docWriter;
  64. }
  65. public void SetUserEntryPoint(SymbolToken tok) {
  66. writer.SetUserEntryPoint(tok);
  67. }
  68. public void DefineSequencePoints(
  69. object doc,
  70. int[] offsets, int[] lines, int[] cols, int[] endLines, int[] endCols) {
  71. ISymUnmanagedDocumentWriter pDoc = (ISymUnmanagedDocumentWriter)doc;
  72. writer.DefineSequencePoints(pDoc, offsets.Length, offsets, lines, cols, endLines, endCols);
  73. }
  74. public void DefineLocalVariable2(
  75. string name,
  76. int attr, SymbolToken tok, int addrKind, int addr1, int addr2, int addr3, int startOfst, int endOfst) {
  77. writer.DefineLocalVariable2(name, attr, tok, addrKind, addr1, addr2, addr3, startOfst, endOfst);
  78. }
  79. public int OpenScope(int startOffset) {
  80. int rslt;
  81. writer.OpenScope(startOffset, out rslt);
  82. return rslt;
  83. }
  84. public void CloseScope(int endOffset) {
  85. writer.CloseScope(endOffset);
  86. }
  87. public void OpenMethod(SymbolToken tok) {
  88. writer.OpenMethod(tok);
  89. }
  90. public void CloseMethod() {
  91. writer.CloseMethod();
  92. }
  93. public byte[] GetDebugInfo() {
  94. int length;
  95. byte[] info = null;
  96. ImageDebugDirectory idd;
  97. writer.GetDebugInfo(out idd, 0, out length, null);
  98. info = new byte[length];
  99. writer.GetDebugInfo(out idd, length, out length, info);
  100. return info;
  101. }
  102. public void Close() {
  103. writer.Close();
  104. }
  105. }
  106. }