71cd1c0f6d010e71c2c44005ab1ee0d181ff1bff
[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 int Version = 23;
22                 public const long Magic   = 0x45e82623fd7fa614;
23
24                 public int total_file_size;
25                 public int source_table_offset;
26                 public int source_table_size;
27                 public int method_count;
28                 public int method_table_offset;
29                 public int method_table_size;
30                 public int line_number_table_offset;
31                 public int line_number_table_size;
32                 public int address_table_size;
33
34                 public OffsetTable (IMonoBinaryReader reader)
35                 {
36                         total_file_size = reader.ReadInt32 ();
37                         source_table_offset = reader.ReadInt32 ();
38                         source_table_size = reader.ReadInt32 ();
39                         method_count = reader.ReadInt32 ();
40                         method_table_offset = reader.ReadInt32 ();
41                         method_table_size = reader.ReadInt32 ();
42                         line_number_table_offset = reader.ReadInt32 ();
43                         line_number_table_size = reader.ReadInt32 ();
44                         address_table_size = reader.ReadInt32 ();
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 int Row;
64                 public readonly int Offset;
65
66                 public LineNumberEntry (int row, int offset)
67                 {
68                         this.Row = row;
69                         this.Offset = offset;
70                 }
71
72                 internal LineNumberEntry (SourceLine line)
73                         : this (line.Row, line.Offset)
74                 { }
75
76                 public LineNumberEntry (IMonoBinaryReader reader)
77                 {
78                         Row = reader.ReadInt32 ();
79                         Offset = reader.ReadInt32 ();
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 VariableInfo
95         {
96                 public readonly int Index;
97                 public readonly int Offset;
98                 public readonly int Size;
99                 public readonly AddressMode Mode;
100                 public readonly int BeginScope;
101                 public readonly int EndScope;
102
103                 public enum AddressMode : long
104                 {
105                         Stack           = 0,
106                         Register        = 0x10000000,
107                         TwoRegisters    = 0x20000000
108                 }
109
110                 const long AddressModeFlags = 0xf0000000;
111
112                 public static int StructSize {
113                         get {
114                                 return 20;
115                         }
116                 }
117
118                 public VariableInfo (IMonoBinaryReader reader)
119                 {
120                         Index = reader.ReadInt32 ();
121                         Offset = reader.ReadInt32 ();
122                         Size = reader.ReadInt32 ();
123                         BeginScope = reader.ReadInt32 ();
124                         EndScope = reader.ReadInt32 ();
125
126                         Mode = (AddressMode) (Index & AddressModeFlags);
127                         Index = (int) ((long) Index & ~AddressModeFlags);
128
129                         Console.WriteLine (this);
130                 }
131
132                 public override string ToString ()
133                 {
134                         return String.Format ("[VariableInfo {0}:{1:x}:{2:x}:{3:x}:{4:x}:{5:x}]",
135                                               Mode, Index, Offset, Size, BeginScope, EndScope);
136                 }
137         }
138
139         public class MethodAddress
140         {
141                 public readonly long StartAddress;
142                 public readonly long EndAddress;
143                 public readonly int[] LineAddresses;
144
145                 public static int Size {
146                         get {
147                                 return 20;
148                         }
149                 }
150
151                 public MethodAddress (MethodEntry entry, IMonoBinaryReader reader)
152                 {
153                         StartAddress = reader.ReadInt64 ();
154                         EndAddress = reader.ReadInt64 ();
155                         LineAddresses = new int [entry.NumLineNumbers];
156                         for (int i = 0; i < entry.NumLineNumbers; i++)
157                                 LineAddresses [i] = reader.ReadInt32 ();
158                 }
159
160                 public override string ToString ()
161                 {
162                         return String.Format ("[Address {0:x}:{1:x}]",
163                                               StartAddress, EndAddress);
164                 }
165         }
166
167         public class MethodEntry
168         {
169                 public readonly int Token;
170                 public readonly int StartRow;
171                 public readonly int EndRow;
172                 public readonly int NumLineNumbers;
173                 public readonly int HasThis;
174                 public readonly int NumParameters;
175                 public readonly int NumLocals;
176
177                 public readonly int SourceFileOffset;
178                 public readonly int LineNumberTableOffset;
179                 public readonly int AddressTableOffset;
180                 public readonly int VariableTableOffset;
181                 public readonly int AddressTableSize;
182
183                 public readonly string SourceFile = null;
184                 public readonly LineNumberEntry[] LineNumbers = null;
185                 public readonly MethodAddress Address = null;
186                 public readonly VariableInfo ThisVariable = null;
187                 public readonly VariableInfo[] Parameters = null;
188                 public readonly VariableInfo[] Locals = null;
189
190                 public static int Size
191                 {
192                         get {
193                                 return 48;
194                         }
195                 }
196
197                 public MethodEntry (IMonoBinaryReader reader, IMonoBinaryReader address_reader)
198                 {
199                         Token = reader.ReadInt32 ();
200                         StartRow = reader.ReadInt32 ();
201                         EndRow = reader.ReadInt32 ();
202                         HasThis = reader.ReadInt32 ();
203                         NumParameters = reader.ReadInt32 ();
204                         NumLocals = reader.ReadInt32 ();
205
206                         NumLineNumbers = reader.ReadInt32 ();
207                         SourceFileOffset = reader.ReadInt32 ();
208                         LineNumberTableOffset = reader.ReadInt32 ();
209                         AddressTableOffset = reader.ReadInt32 ();
210                         VariableTableOffset = reader.ReadInt32 ();
211                         AddressTableSize = reader.ReadInt32 ();
212
213                         if (SourceFileOffset != 0) {
214                                 long old_pos = reader.Position;
215                                 reader.Position = SourceFileOffset;
216                                 int source_file_length = reader.ReadInt32 ();
217                                 byte[] source_file = reader.ReadBuffer (source_file_length);
218                                 SourceFile = Encoding.UTF8.GetString (source_file);
219                                 reader.Position = old_pos;
220                         }
221
222                         if (LineNumberTableOffset != 0) {
223                                 long old_pos = reader.Position;
224                                 reader.Position = LineNumberTableOffset;
225
226                                 LineNumbers = new LineNumberEntry [NumLineNumbers];
227
228                                 for (int i = 0; i < NumLineNumbers; i++)
229                                         LineNumbers [i] = new LineNumberEntry (reader);
230
231                                 reader.Position = old_pos;
232                         }
233
234                         if (AddressTableSize != 0) {
235                                 long old_pos = address_reader.Position;
236                                 address_reader.Position = AddressTableOffset;
237                                 int is_valid = address_reader.ReadInt32 ();
238                                 if (is_valid != 0)
239                                         Address = new MethodAddress (this, address_reader);
240                                 address_reader.Position = VariableTableOffset;
241                                 if (HasThis != 0)
242                                         ThisVariable = new VariableInfo (address_reader);
243                                 Parameters = new VariableInfo [NumParameters];
244                                 for (int i = 0; i < NumParameters; i++)
245                                         Parameters [i] = new VariableInfo (address_reader);
246                                 Locals = new VariableInfo [NumLocals];
247                                 for (int i = 0; i < NumLocals; i++)
248                                         Locals [i] = new VariableInfo (address_reader);
249                                 address_reader.Position = old_pos;
250                         }
251                 }
252
253                 internal MethodEntry (int token, int sf_offset, string source_file,
254                                       bool has_this, int num_params, int num_locals,
255                                       LineNumberEntry[] lines, int lnt_offset,
256                                       int addrtab_offset, int vartab_offset, int addrtab_size,
257                                       int start_row, int end_row)
258                 {
259                         this.Token = token;
260                         this.StartRow = start_row;
261                         this.EndRow = end_row;
262                         this.NumLineNumbers = lines.Length;
263                         this.HasThis = has_this ? 1 : 0;
264                         this.NumParameters = num_params;
265                         this.NumLocals = num_locals;
266                         this.SourceFileOffset = sf_offset;
267                         this.LineNumberTableOffset = lnt_offset;
268                         this.AddressTableOffset = addrtab_offset;
269                         this.VariableTableOffset = vartab_offset;
270                         this.AddressTableSize = addrtab_size;
271                         this.SourceFile = source_file;
272                         this.LineNumbers = lines;
273                 }
274
275                 internal void Write (BinaryWriter bw)
276                 {
277                         bw.Write (Token);
278                         bw.Write (StartRow);
279                         bw.Write (EndRow);
280                         bw.Write (HasThis);
281                         bw.Write (NumParameters);
282                         bw.Write (NumLocals);
283                         bw.Write (NumLineNumbers);
284                         bw.Write (SourceFileOffset);
285                         bw.Write (LineNumberTableOffset);
286                         bw.Write (AddressTableOffset);
287                         bw.Write (VariableTableOffset);
288                         bw.Write (AddressTableSize);
289                 }
290
291                 public override string ToString ()
292                 {
293                         return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {5}:{6}:{7}:{8}]",
294                                               Token, SourceFile, StartRow, EndRow, NumLineNumbers,
295                                               SourceFileOffset, LineNumberTableOffset, AddressTableOffset,
296                                               AddressTableSize);
297                 }
298         }
299 }