2002-08-27 Martin Baulig <martin@gnome.org>
[mono.git] / mcs / class / Mono.CSharp.Debugger / MonoSymbolTable.cs
1 //
2 // System.Diagnostics.SymbolStore/MonoSymbolTable.cs
3 //
4 // Author:
5 //   Martin Baulig (martin@gnome.org)
6 //
7 // (C) 2002 Ximian, Inc.  http://www.ximian.com
8 //
9
10 using System;
11 using System.Reflection;
12 using System.Reflection.Emit;
13 using System.Collections;
14 using System.Text;
15 using System.IO;
16         
17 namespace Mono.CSharp.Debugger
18 {
19         public struct OffsetTable
20         {
21                 public const uint Version = 17;
22                 public const long Magic   = 0x45e82623fd7fa614;
23
24                 public uint total_file_size;
25                 public uint source_table_offset;
26                 public uint source_table_size;
27                 public uint method_count;
28                 public uint method_table_offset;
29                 public uint method_table_size;
30                 public uint line_number_table_offset;
31                 public uint line_number_table_size;
32                 public uint address_table_size;
33
34                 public OffsetTable (BinaryReader reader)
35                 {
36                         total_file_size = reader.ReadUInt32 ();
37                         source_table_offset = reader.ReadUInt32 ();
38                         source_table_size = reader.ReadUInt32 ();
39                         method_count = reader.ReadUInt32 ();
40                         method_table_offset = reader.ReadUInt32 ();
41                         method_table_size = reader.ReadUInt32 ();
42                         line_number_table_offset = reader.ReadUInt32 ();
43                         line_number_table_size = reader.ReadUInt32 ();
44                         address_table_size = reader.ReadUInt32 ();
45                 }
46
47                 public void Write (BinaryWriter bw)
48                 {
49                         bw.Write (total_file_size);
50                         bw.Write (source_table_offset);
51                         bw.Write (source_table_size);
52                         bw.Write (method_count);
53                         bw.Write (method_table_offset);
54                         bw.Write (method_table_size);
55                         bw.Write (line_number_table_offset);
56                         bw.Write (line_number_table_size);
57                         bw.Write (address_table_size);
58                 }
59         }
60
61         public struct LineNumberEntry
62         {
63                 public readonly uint Row;
64                 public readonly uint Offset;
65
66                 public LineNumberEntry (uint row, uint offset)
67                 {
68                         this.Row = row;
69                         this.Offset = offset;
70                 }
71
72                 internal LineNumberEntry (ISourceLine line)
73                         : this ((uint) line.Row, (uint) line.Offset)
74                 { }
75
76                 public LineNumberEntry (BinaryReader reader)
77                 {
78                         Row = reader.ReadUInt32 ();
79                         Offset = reader.ReadUInt32 ();
80                 }
81
82                 internal void Write (BinaryWriter bw)
83                 {
84                         bw.Write (Row);
85                         bw.Write (Offset);
86                 }
87
88                 public override string ToString ()
89                 {
90                         return String.Format ("[Line {0}:{1}]", Row, Offset);
91                 }
92         }
93
94         public class MethodAddress
95         {
96                 public readonly ulong StartAddress;
97                 public readonly ulong EndAddress;
98                 public readonly uint[] LineAddresses;
99
100                 public static int Size {
101                         get {
102                                 return 3 * sizeof (ulong);
103                         }
104                 }
105
106                 public MethodAddress (MethodEntry entry, BinaryReader reader)
107                 {
108                         StartAddress = reader.ReadUInt64 ();
109                         EndAddress = reader.ReadUInt64 ();
110                         LineAddresses = new uint [entry.NumLineNumbers];
111                         for (int i = 0; i < entry.NumLineNumbers; i++)
112                                 LineAddresses [i] = reader.ReadUInt32 ();
113                 }
114
115                 public override string ToString ()
116                 {
117                         return String.Format ("[Address {0:x}:{1:x}]",
118                                               StartAddress, EndAddress);
119                 }
120         }
121
122         public class MethodEntry
123         {
124                 public readonly uint Token;
125                 public readonly uint StartRow;
126                 public readonly uint EndRow;
127                 public readonly uint NumLineNumbers;
128
129                 public readonly uint SourceFileOffset;
130                 public readonly uint LineNumberTableOffset;
131                 public readonly uint AddressTableOffset;
132                 public readonly uint AddressTableSize;
133
134                 public readonly string SourceFile = null;
135                 public readonly LineNumberEntry[] LineNumbers = null;
136                 public readonly MethodAddress Address = null;
137
138                 public MethodEntry (BinaryReader reader, BinaryReader address_reader)
139                 {
140                         Token = reader.ReadUInt32 ();
141                         StartRow = reader.ReadUInt32 ();
142                         EndRow = reader.ReadUInt32 ();
143                         NumLineNumbers = reader.ReadUInt32 ();
144
145                         SourceFileOffset = reader.ReadUInt32 ();
146                         LineNumberTableOffset = reader.ReadUInt32 ();
147                         AddressTableOffset = reader.ReadUInt32 ();
148                         AddressTableSize = reader.ReadUInt32 ();
149
150                         if (SourceFileOffset != 0) {
151                                 long old_pos = reader.BaseStream.Position;
152                                 reader.BaseStream.Position = SourceFileOffset;
153                                 SourceFile = reader.ReadString ();
154                                 reader.BaseStream.Position = old_pos;
155                         }
156
157                         // Console.WriteLine ("METHOD ENTRY: " + this);
158
159                         if (LineNumberTableOffset != 0) {
160                                 long old_pos = reader.BaseStream.Position;
161                                 reader.BaseStream.Position = LineNumberTableOffset;
162
163                                 LineNumbers = new LineNumberEntry [NumLineNumbers];
164
165                                 for (int i = 0; i < NumLineNumbers; i++) {
166                                         LineNumbers [i] = new LineNumberEntry (reader);
167                                         // Console.WriteLine ("LINE: " + LineNumbers [i]);
168                                 }
169
170                                 reader.BaseStream.Position = old_pos;
171                         }
172
173                         if (AddressTableSize != 0) {
174                                 long old_pos = address_reader.BaseStream.Position;
175                                 address_reader.BaseStream.Position = AddressTableOffset;
176                                 uint is_valid = address_reader.ReadUInt32 ();
177                                 if (is_valid != 0) {
178                                         Address = new MethodAddress (this, address_reader);
179                                         // Console.WriteLine ("ADDRESS: " + Address);
180                                 }
181                                 address_reader.BaseStream.Position = old_pos;
182                         }
183                 }
184
185                 internal MethodEntry (uint token, uint sf_offset, string source_file,
186                                       LineNumberEntry[] lines, uint lnt_offset,
187                                       uint addrtab_offset, uint addrtab_size,
188                                       uint start_row, uint end_row)
189                 {
190                         this.Token = token;
191                         this.StartRow = start_row;
192                         this.EndRow = end_row;
193                         this.NumLineNumbers = (uint) lines.Length;
194                         this.SourceFileOffset = sf_offset;
195                         this.LineNumberTableOffset = lnt_offset;
196                         this.AddressTableOffset = addrtab_offset;
197                         this.AddressTableSize = addrtab_size;
198                         this.SourceFile = source_file;
199                         this.LineNumbers = lines;
200                 }
201
202                 internal void Write (BinaryWriter bw)
203                 {
204                         bw.Write (Token);
205                         bw.Write (StartRow);
206                         bw.Write (EndRow);
207                         bw.Write (NumLineNumbers);
208                         bw.Write (SourceFileOffset);
209                         bw.Write (LineNumberTableOffset);
210                         bw.Write (AddressTableOffset);
211                         bw.Write (AddressTableSize);
212                 }
213
214                 public override string ToString ()
215                 {
216                         return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {5}:{6}:{7}:{8}]",
217                                               Token, SourceFile, StartRow, EndRow, NumLineNumbers,
218                                               SourceFileOffset, LineNumberTableOffset, AddressTableOffset,
219                                               AddressTableSize);
220                 }
221         }
222 }