Merge pull request #3066 from alexanderkyte/pedump_sgen
[mono.git] / mcs / tools / mdbdump / mdbdump.cs
index aa7c4b0809d55e30a6e68df673f496385f634ef7..559bc2b9b3f5a99eeecc7b0fe384f4b0b82ac3d7 100644 (file)
@@ -2,24 +2,113 @@ using System;
 using System.IO;
 using Mono.CompilerServices.SymbolWriter;
 using Mono.Cecil;
+using System.Text;
+using System.Xml;
+using System.Globalization;
 
 public class MdbDump
 {
-       public static int Main (String[] args) {
+       public static int Main (String[] args)
+       {
                if (args.Length < 1) {
                        Console.Error.WriteLine ("Usage: mdbdump <assembly>");
                        return 1;
                }
 
-               var assembly = AssemblyDefinition.ReadAssembly (args [0]);
+               var assembly = AssemblyDefinition.ReadAssembly (args[0]);
+
+               var f = MonoSymbolFile.ReadSymbolFile (args[0] + ".mdb");
+               DumpSymbolFile (assembly, f, Console.Out);
 
-               var f = MonoSymbolFile.ReadSymbolFile (args [0] + ".mdb");
-               foreach (var m in f.Methods) {
-                       var lt = m.GetLineNumberTable ();
-                       Console.WriteLine (assembly.MainModule.LookupToken (m.Token));
-                       foreach (var lne in lt.LineNumbers)
-                               Console.WriteLine (lne);
-               }
                return 0;
        }
+
+       static string ChecksumToString (byte[] checksum)
+       {
+               var sb = new StringBuilder (checksum.Length * 2);
+               for (int i = 0; i < checksum.Length; i++) {
+                       sb.Append ("0123456789abcdef"[checksum[i] >> 4]);
+                       sb.Append ("0123456789abcdef"[checksum[i] & 0x0F]);
+               }
+
+               return sb.ToString ();
+       }
+
+       static string IntToHex (int value)
+       {
+               return "0x" + value.ToString ("x", CultureInfo.InvariantCulture);
+       }
+
+       static void DumpSymbolFile (AssemblyDefinition assembly, MonoSymbolFile symbolFile, TextWriter output)
+       {
+               using (XmlTextWriter writer = new XmlTextWriter (output)) {
+                       writer.Formatting = Formatting.Indented;
+
+                       writer.WriteStartDocument ();
+
+                       writer.WriteStartElement ("symbols");
+
+                       writer.WriteStartElement ("files");
+                       foreach (var file in symbolFile.Sources) {
+                               writer.WriteStartElement ("file");
+                               writer.WriteAttributeString ("id", file.Index.ToString ());
+                               writer.WriteAttributeString ("name", Path.GetFileName (file.FileName));
+                               var checksum = file.Checksum;
+                               if (checksum != null)
+                                       writer.WriteAttributeString ("checksum", ChecksumToString (checksum));
+
+                               writer.WriteEndElement ();
+                       }
+                       writer.WriteEndElement ();
+
+                       writer.WriteStartElement ("methods");
+                       foreach (var method in symbolFile.Methods) {
+                               writer.WriteStartElement ("method");
+                               writer.WriteAttributeString ("token", IntToHex (method.Token));
+                               writer.WriteAttributeString ("signature", assembly.MainModule.LookupToken (method.Token).ToString ());
+
+                               var il_entries = method.GetLineNumberTable ();
+                               writer.WriteStartElement ("sequencepoints");
+                               foreach (var entry in il_entries.LineNumbers) {
+                                       writer.WriteStartElement ("entry");
+                                       writer.WriteAttributeString ("il", IntToHex (entry.Offset));
+                                       writer.WriteAttributeString ("row", entry.Row.ToString ());
+                                       writer.WriteAttributeString ("col", entry.Column.ToString ());
+                                       if (entry.EndRow != -1 || entry.EndColumn != -1) {
+                                               writer.WriteAttributeString ("end_row", entry.EndRow.ToString ());
+                                               writer.WriteAttributeString ("end_col", entry.EndColumn.ToString ());
+                                       }
+                                       writer.WriteAttributeString ("file_ref", entry.File.ToString ());
+                                       writer.WriteEndElement ();
+                               }
+                               writer.WriteEndElement ();
+
+                               writer.WriteStartElement ("locals");
+                               foreach (var local in method.GetLocals ()) {
+                                       writer.WriteStartElement ("entry");
+                                       writer.WriteAttributeString ("name", local.Name);
+                                       writer.WriteAttributeString ("il_index", local.Index.ToString ());
+                                       writer.WriteAttributeString ("scope_ref", local.BlockIndex.ToString ());
+                                       writer.WriteEndElement ();
+                               }
+                               writer.WriteEndElement ();
+
+                               writer.WriteStartElement ("scopes");
+                               foreach (var scope in method.GetCodeBlocks ()) {
+                                       writer.WriteStartElement ("entry");
+                                       writer.WriteAttributeString ("index", scope.Index.ToString ());
+                                       writer.WriteAttributeString ("start", IntToHex (scope.StartOffset));
+                                       writer.WriteAttributeString ("end", IntToHex (scope.EndOffset));
+                                       writer.WriteEndElement ();
+                               }
+                               writer.WriteEndElement ();
+
+                               writer.WriteEndElement ();
+                       }
+                       writer.WriteEndElement ();
+
+                       writer.WriteEndElement ();
+                       writer.WriteEndDocument ();
+               }
+       }
 }