2002-10-18 Duncan Mak <duncan@ximian.com>
[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 = 28;
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 local_variable_table_offset;
33                 public int local_variable_table_size;
34                 public int source_file_table_offset;
35                 public int source_file_table_size;
36                 public int source_file_count;
37                 public int type_count;
38                 public int type_index_table_offset;
39                 public int type_index_table_size;
40
41                 public OffsetTable (IMonoBinaryReader reader)
42                 {
43                         total_file_size = reader.ReadInt32 ();
44                         source_table_offset = reader.ReadInt32 ();
45                         source_table_size = reader.ReadInt32 ();
46                         method_count = reader.ReadInt32 ();
47                         method_table_offset = reader.ReadInt32 ();
48                         method_table_size = reader.ReadInt32 ();
49                         line_number_table_offset = reader.ReadInt32 ();
50                         line_number_table_size = reader.ReadInt32 ();
51                         local_variable_table_offset = reader.ReadInt32 ();
52                         local_variable_table_size = reader.ReadInt32 ();
53                         source_file_table_offset = reader.ReadInt32 ();
54                         source_file_table_size = reader.ReadInt32 ();
55                         source_file_count = reader.ReadInt32 ();
56                         type_count = reader.ReadInt32 ();
57                         type_index_table_offset = reader.ReadInt32 ();
58                         type_index_table_size = reader.ReadInt32 ();
59                 }
60
61                 public void Write (BinaryWriter bw)
62                 {
63                         bw.Write (total_file_size);
64                         bw.Write (source_table_offset);
65                         bw.Write (source_table_size);
66                         bw.Write (method_count);
67                         bw.Write (method_table_offset);
68                         bw.Write (method_table_size);
69                         bw.Write (line_number_table_offset);
70                         bw.Write (line_number_table_size);
71                         bw.Write (local_variable_table_offset);
72                         bw.Write (local_variable_table_size);
73                         bw.Write (source_file_table_offset);
74                         bw.Write (source_file_table_size);
75                         bw.Write (source_file_count);
76                         bw.Write (type_count);
77                         bw.Write (type_index_table_offset);
78                         bw.Write (type_index_table_size);
79                 }
80         }
81
82         public struct LineNumberEntry
83         {
84                 public readonly int Row;
85                 public readonly int Offset;
86
87                 public LineNumberEntry (int row, int offset)
88                 {
89                         this.Row = row;
90                         this.Offset = offset;
91                 }
92
93                 internal LineNumberEntry (SourceLine line)
94                         : this (line.Row, line.Offset)
95                 { }
96
97                 public LineNumberEntry (IMonoBinaryReader reader)
98                 {
99                         Row = reader.ReadInt32 ();
100                         Offset = reader.ReadInt32 ();
101                 }
102
103                 internal void Write (BinaryWriter bw)
104                 {
105                         bw.Write (Row);
106                         bw.Write (Offset);
107                 }
108
109                 public override string ToString ()
110                 {
111                         return String.Format ("[Line {0}:{1}]", Row, Offset);
112                 }
113         }
114
115         public struct LocalVariableEntry
116         {
117                 public readonly string Name;
118                 public readonly FieldAttributes Attributes;
119                 public readonly byte[] Signature;
120
121                 public LocalVariableEntry (string Name, FieldAttributes Attributes, byte[] Signature)
122                 {
123                         this.Name = Name;
124                         this.Attributes = Attributes;
125                         this.Signature = Signature;
126                 }
127
128                 public LocalVariableEntry (IMonoBinaryReader reader)
129                 {
130                         int name_length = reader.ReadInt32 ();
131                         byte[] name = reader.ReadBuffer (name_length);
132                         Name = Encoding.UTF8.GetString (name);
133                         Attributes = (FieldAttributes) reader.ReadInt32 ();
134                         int sig_length = reader.ReadInt32 ();
135                         Signature = reader.ReadBuffer (sig_length);
136                 }
137
138                 internal void Write (BinaryWriter bw)
139                 {
140                         byte[] name = Encoding.UTF8.GetBytes (Name);
141                         bw.Write ((int) name.Length);
142                         bw.Write (name);
143                         bw.Write ((int) Attributes);
144                         bw.Write ((int) Signature.Length);
145                         bw.Write (Signature);
146                 }
147
148                 public override string ToString ()
149                 {
150                         return String.Format ("[LocalVariable {0}:{1}]", Name, Attributes);
151                 }
152         }
153
154         public class SourceFileEntry
155         {
156                 public readonly string SourceFile;
157
158                 IMonoBinaryReader reader;
159                 long method_position;
160                 ArrayList methods;
161                 int count;
162
163                 internal SourceFileEntry (string source_file)
164                 {
165                         this.SourceFile = source_file;
166                         this.methods = new ArrayList ();
167                         this.count = 0;
168                 }
169
170                 internal void AddMethod (MethodSourceEntry method)
171                 {
172                         methods.Add (method);
173                         count++;
174                 }
175
176                 internal void Write (BinaryWriter bw)
177                 {
178                         byte[] name = Encoding.UTF8.GetBytes (SourceFile);
179                         bw.Write ((int) name.Length);
180                         bw.Write (name);
181
182                         methods.Sort ();
183                         bw.Write (methods.Count);
184                         foreach (MethodSourceEntry method in methods)
185                                 method.Write (bw);
186                 }
187
188                 public SourceFileEntry (IMonoBinaryReader reader)
189                 {
190                         int name_length = reader.ReadInt32 ();
191                         byte[] name = reader.ReadBuffer (name_length);
192                         SourceFile = Encoding.UTF8.GetString (name);
193
194                         count = reader.ReadInt32 ();
195                         this.reader = reader;
196                         this.method_position = reader.Position;
197
198                         reader.Position += count * MethodSourceEntry.Size;
199                 }
200
201                 public MethodSourceEntry[] Methods {
202                         get {
203                                 read_methods ();
204                                 MethodSourceEntry[] retval = new MethodSourceEntry [methods.Count];
205                                 methods.CopyTo (retval, 0);
206                                 return retval;
207                         }
208                 }
209
210                 void read_methods ()
211                 {
212                         if (methods != null)
213                                 return;
214
215                         reader.Position = method_position;
216                         methods = new ArrayList ();
217                         for (int i = 0; i < count; i++)
218                                 methods.Add (new MethodSourceEntry (reader));
219                 }
220
221                 public override string ToString ()
222                 {
223                         return String.Format ("SourceFileEntry ({0}:{1})", SourceFile, count);
224                 }
225         }
226
227         public struct MethodSourceEntry : IComparable
228         {
229                 public readonly int Index;
230                 public readonly int FileOffset;
231                 public readonly int StartRow;
232                 public readonly int EndRow;
233
234                 public MethodSourceEntry (int index, int file_offset, int start, int end)
235                 {
236                         this.Index = index;
237                         this.FileOffset = file_offset;
238                         this.StartRow = start;
239                         this.EndRow = end;
240                 }
241
242                 public MethodSourceEntry (IMonoBinaryReader reader)
243                 {
244                         Index = reader.ReadInt32 ();
245                         FileOffset = reader.ReadInt32 ();
246                         StartRow = reader.ReadInt32 ();
247                         EndRow = reader.ReadInt32 ();
248                 }
249
250                 public static int Size
251                 {
252                         get {
253                                 return 16;
254                         }
255                 }
256
257                 internal void Write (BinaryWriter bw)
258                 {
259                         bw.Write (Index);
260                         bw.Write (FileOffset);
261                         bw.Write (StartRow);
262                         bw.Write (EndRow);
263                 }
264
265                 public int CompareTo (object obj)
266                 {
267                         MethodSourceEntry method = (MethodSourceEntry) obj;
268
269                         if (method.StartRow < StartRow)
270                                 return -1;
271                         else if (method.StartRow > StartRow)
272                                 return 1;
273                         else
274                                 return 0;
275                 }
276
277                 public override string ToString ()
278                 {
279                         return String.Format ("MethodSourceEntry ({0}:{1}:{2}:{3})",
280                                               Index, FileOffset, StartRow, EndRow);
281                 }
282         }
283
284         public class MethodEntry
285         {
286                 public readonly int Token;
287                 public readonly int StartRow;
288                 public readonly int EndRow;
289                 public readonly int NumLineNumbers;
290                 public readonly int ThisTypeIndex;
291                 public readonly int NumParameters;
292                 public readonly int NumLocals;
293
294                 public int TypeIndexTableOffset;
295                 public int LocalVariableTableOffset;
296                 public readonly int SourceFileOffset;
297                 public readonly int LineNumberTableOffset;
298
299                 public readonly string SourceFile = null;
300                 public readonly LineNumberEntry[] LineNumbers = null;
301                 public readonly int[] ParamTypeIndices = null;
302                 public readonly int[] LocalTypeIndices = null;
303                 public readonly LocalVariableEntry[] Locals = null;
304
305                 public static int Size
306                 {
307                         get {
308                                 return 44;
309                         }
310                 }
311
312                 public MethodEntry (IMonoBinaryReader reader)
313                 {
314                         Token = reader.ReadInt32 ();
315                         StartRow = reader.ReadInt32 ();
316                         EndRow = reader.ReadInt32 ();
317                         ThisTypeIndex = reader.ReadInt32 ();
318                         NumParameters = reader.ReadInt32 ();
319                         NumLocals = reader.ReadInt32 ();
320                         NumLineNumbers = reader.ReadInt32 ();
321                         TypeIndexTableOffset = reader.ReadInt32 ();
322                         LocalVariableTableOffset = reader.ReadInt32 ();
323                         SourceFileOffset = reader.ReadInt32 ();
324                         LineNumberTableOffset = reader.ReadInt32 ();
325
326                         if (SourceFileOffset != 0) {
327                                 long old_pos = reader.Position;
328                                 reader.Position = SourceFileOffset;
329                                 int source_file_length = reader.ReadInt32 ();
330                                 byte[] source_file = reader.ReadBuffer (source_file_length);
331                                 SourceFile = Encoding.UTF8.GetString (source_file);
332                                 reader.Position = old_pos;
333                         }
334
335                         if (LineNumberTableOffset != 0) {
336                                 long old_pos = reader.Position;
337                                 reader.Position = LineNumberTableOffset;
338
339                                 LineNumbers = new LineNumberEntry [NumLineNumbers];
340
341                                 for (int i = 0; i < NumLineNumbers; i++)
342                                         LineNumbers [i] = new LineNumberEntry (reader);
343
344                                 reader.Position = old_pos;
345                         }
346
347                         if (LocalVariableTableOffset != 0) {
348                                 long old_pos = reader.Position;
349                                 reader.Position = LocalVariableTableOffset;
350
351                                 Locals = new LocalVariableEntry [NumLocals];
352
353                                 for (int i = 0; i < NumLocals; i++)
354                                         Locals [i] = new LocalVariableEntry (reader);
355
356                                 reader.Position = old_pos;
357                         }
358
359                         if (TypeIndexTableOffset != 0) {
360                                 long old_pos = reader.Position;
361                                 reader.Position = TypeIndexTableOffset;
362
363                                 ParamTypeIndices = new int [NumParameters];
364                                 LocalTypeIndices = new int [NumLocals];
365
366                                 for (int i = 0; i < NumParameters; i++)
367                                         ParamTypeIndices [i] = reader.ReadInt32 ();
368                                 for (int i = 0; i < NumLocals; i++)
369                                         LocalTypeIndices [i] = reader.ReadInt32 ();
370
371                                 reader.Position = old_pos;
372                         }
373                 }
374
375                 internal MethodEntry (int token, int sf_offset, string source_file,
376                                       int this_type_index, int[] param_type_indices,
377                                       int[] local_type_indices, LocalVariableEntry[] locals,
378                                       LineNumberEntry[] lines, int lnt_offset,
379                                       int start_row, int end_row)
380                 {
381                         this.Token = token;
382                         this.StartRow = start_row;
383                         this.EndRow = end_row;
384                         this.NumLineNumbers = lines.Length;
385                         this.ThisTypeIndex = this_type_index;
386                         this.NumParameters = param_type_indices.Length;
387                         this.NumLocals = local_type_indices.Length;
388                         this.ParamTypeIndices = param_type_indices;
389                         this.LocalTypeIndices = local_type_indices;
390                         this.Locals = locals;
391                         this.SourceFileOffset = sf_offset;
392                         this.LineNumberTableOffset = lnt_offset;
393                         this.SourceFile = source_file;
394                         this.LineNumbers = lines;
395                 }
396
397                 internal void Write (BinaryWriter bw)
398                 {
399                         bw.Write (Token);
400                         bw.Write (StartRow);
401                         bw.Write (EndRow);
402                         bw.Write (ThisTypeIndex);
403                         bw.Write (NumParameters);
404                         bw.Write (NumLocals);
405                         bw.Write (NumLineNumbers);
406                         bw.Write (TypeIndexTableOffset);
407                         bw.Write (LocalVariableTableOffset);
408                         bw.Write (SourceFileOffset);
409                         bw.Write (LineNumberTableOffset);
410                 }
411
412                 public override string ToString ()
413                 {
414                         return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {5}:{6}]",
415                                               Token, SourceFile, StartRow, EndRow,
416                                               NumLineNumbers, SourceFileOffset, LineNumberTableOffset);
417                 }
418         }
419 }