Merge pull request #2753 from xmcclure/checked-build-updates
[mono.git] / mcs / tools / mdbdump / mdbdump.cs
1 using System;
2 using System.IO;
3 using Mono.CompilerServices.SymbolWriter;
4 using Mono.Cecil;
5 using System.Text;
6 using System.Xml;
7 using System.Globalization;
8
9 public class MdbDump
10 {
11         public static int Main (String[] args)
12         {
13                 if (args.Length < 1) {
14                         Console.Error.WriteLine ("Usage: mdbdump <assembly>");
15                         return 1;
16                 }
17
18                 var assembly = AssemblyDefinition.ReadAssembly (args[0]);
19
20                 var f = MonoSymbolFile.ReadSymbolFile (args[0] + ".mdb");
21                 DumpSymbolFile (assembly, f, Console.Out);
22
23                 return 0;
24         }
25
26         static string ChecksumToString (byte[] checksum)
27         {
28                 var sb = new StringBuilder (checksum.Length * 2);
29                 for (int i = 0; i < checksum.Length; i++) {
30                         sb.Append ("0123456789abcdef"[checksum[i] >> 4]);
31                         sb.Append ("0123456789abcdef"[checksum[i] & 0x0F]);
32                 }
33
34                 return sb.ToString ();
35         }
36
37         static string IntToHex (int value)
38         {
39                 return "0x" + value.ToString ("x", CultureInfo.InvariantCulture);
40         }
41
42         static void DumpSymbolFile (AssemblyDefinition assembly, MonoSymbolFile symbolFile, TextWriter output)
43         {
44                 using (XmlTextWriter writer = new XmlTextWriter (output)) {
45                         writer.Formatting = Formatting.Indented;
46
47                         writer.WriteStartDocument ();
48
49                         writer.WriteStartElement ("symbols");
50
51                         writer.WriteStartElement ("files");
52                         foreach (var file in symbolFile.Sources) {
53                                 writer.WriteStartElement ("file");
54                                 writer.WriteAttributeString ("id", file.Index.ToString ());
55                                 writer.WriteAttributeString ("name", Path.GetFileName (file.FileName));
56                                 var checksum = file.Checksum;
57                                 if (checksum != null)
58                                         writer.WriteAttributeString ("checksum", ChecksumToString (checksum));
59
60                                 writer.WriteEndElement ();
61                         }
62                         writer.WriteEndElement ();
63
64                         writer.WriteStartElement ("methods");
65                         foreach (var method in symbolFile.Methods) {
66                                 writer.WriteStartElement ("method");
67                                 writer.WriteAttributeString ("token", IntToHex (method.Token));
68                                 writer.WriteAttributeString ("signature", assembly.MainModule.LookupToken (method.Token).ToString ());
69
70                                 var il_entries = method.GetLineNumberTable ();
71                                 writer.WriteStartElement ("sequencepoints");
72                                 foreach (var entry in il_entries.LineNumbers) {
73                                         writer.WriteStartElement ("entry");
74                                         writer.WriteAttributeString ("il", IntToHex (entry.Offset));
75                                         writer.WriteAttributeString ("row", entry.Row.ToString ());
76                                         writer.WriteAttributeString ("col", entry.Column.ToString ());
77                                         if (entry.EndRow != -1 || entry.EndColumn != -1) {
78                                                 writer.WriteAttributeString ("end_row", entry.EndRow.ToString ());
79                                                 writer.WriteAttributeString ("end_col", entry.EndColumn.ToString ());
80                                         }
81                                         writer.WriteAttributeString ("file_ref", entry.File.ToString ());
82                                         writer.WriteEndElement ();
83                                 }
84                                 writer.WriteEndElement ();
85
86                                 writer.WriteStartElement ("locals");
87                                 foreach (var local in method.GetLocals ()) {
88                                         writer.WriteStartElement ("entry");
89                                         writer.WriteAttributeString ("name", local.Name);
90                                         writer.WriteAttributeString ("il_index", local.Index.ToString ());
91                                         writer.WriteAttributeString ("scope_ref", local.BlockIndex.ToString ());
92                                         writer.WriteEndElement ();
93                                 }
94                                 writer.WriteEndElement ();
95
96                                 writer.WriteStartElement ("scopes");
97                                 foreach (var scope in method.GetCodeBlocks ()) {
98                                         writer.WriteStartElement ("entry");
99                                         writer.WriteAttributeString ("index", scope.Index.ToString ());
100                                         writer.WriteAttributeString ("start", IntToHex (scope.StartOffset));
101                                         writer.WriteAttributeString ("end", IntToHex (scope.EndOffset));
102                                         writer.WriteEndElement ();
103                                 }
104                                 writer.WriteEndElement ();
105
106                                 writer.WriteEndElement ();
107                         }
108                         writer.WriteEndElement ();
109
110                         writer.WriteEndElement ();
111                         writer.WriteEndDocument ();
112                 }
113         }
114 }