2002-10-13 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 int  Version = 27;
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                 public readonly MethodSourceEntry[] Methods = null;
158
159                 ArrayList methods;
160                 int count;
161
162                 internal SourceFileEntry (string source_file)
163                 {
164                         this.SourceFile = source_file;
165                         this.methods = new ArrayList ();
166                         this.count = 0;
167                 }
168
169                 internal void AddMethod (MethodSourceEntry method)
170                 {
171                         methods.Add (method);
172                         count++;
173                 }
174
175                 internal void Write (BinaryWriter bw)
176                 {
177                         byte[] name = Encoding.UTF8.GetBytes (SourceFile);
178                         bw.Write ((int) name.Length);
179                         bw.Write (name);
180
181                         methods.Sort ();
182                         bw.Write (methods.Count);
183                         foreach (MethodSourceEntry method in methods)
184                                 method.Write (bw);
185                 }
186
187                 public SourceFileEntry (IMonoBinaryReader reader)
188                 {
189                         int name_length = reader.ReadInt32 ();
190                         byte[] name = reader.ReadBuffer (name_length);
191                         SourceFile = Encoding.UTF8.GetString (name);
192
193                         count = reader.ReadInt32 ();
194                         Methods = new MethodSourceEntry [count];
195                         for (int i = 0; i < count; i++)
196                                 Methods [i] = new MethodSourceEntry (reader);
197                 }
198
199                 public override string ToString ()
200                 {
201                         return String.Format ("SourceFileEntry ({0}:{1})", SourceFile, count);
202                 }
203         }
204
205         public class MethodSourceEntry : IComparable
206         {
207                 public readonly int Index;
208                 public readonly int FileOffset;
209                 public readonly int StartRow;
210                 public readonly int EndRow;
211
212                 public MethodSourceEntry (int index, int file_offset, int start, int end)
213                 {
214                         this.Index = index;
215                         this.FileOffset = file_offset;
216                         this.StartRow = start;
217                         this.EndRow = end;
218                 }
219
220                 public MethodSourceEntry (IMonoBinaryReader reader)
221                 {
222                         Index = reader.ReadInt32 ();
223                         FileOffset = reader.ReadInt32 ();
224                         StartRow = reader.ReadInt32 ();
225                         EndRow = reader.ReadInt32 ();
226                 }
227
228                 internal void Write (BinaryWriter bw)
229                 {
230                         bw.Write (Index);
231                         bw.Write (FileOffset);
232                         bw.Write (StartRow);
233                         bw.Write (EndRow);
234                 }
235
236                 public int CompareTo (object obj)
237                 {
238                         MethodSourceEntry method = (MethodSourceEntry) obj;
239
240                         if (method.StartRow < StartRow)
241                                 return -1;
242                         else if (method.StartRow > StartRow)
243                                 return 1;
244                         else
245                                 return 0;
246                 }
247
248                 public override string ToString ()
249                 {
250                         return String.Format ("MethodSourceEntry ({0}:{1}:{2}:{3})",
251                                               Index, FileOffset, StartRow, EndRow);
252                 }
253         }
254
255         public class MethodEntry
256         {
257                 public readonly int Token;
258                 public readonly int StartRow;
259                 public readonly int EndRow;
260                 public readonly int NumLineNumbers;
261                 public readonly int ThisTypeIndex;
262                 public readonly int NumParameters;
263                 public readonly int NumLocals;
264
265                 public int TypeIndexTableOffset;
266                 public int LocalVariableTableOffset;
267                 public readonly int SourceFileOffset;
268                 public readonly int LineNumberTableOffset;
269
270                 public readonly string SourceFile = null;
271                 public readonly LineNumberEntry[] LineNumbers = null;
272                 public readonly int[] ParamTypeIndices = null;
273                 public readonly int[] LocalTypeIndices = null;
274                 public readonly LocalVariableEntry[] Locals = null;
275
276                 public static int Size
277                 {
278                         get {
279                                 return 44;
280                         }
281                 }
282
283                 public MethodEntry (IMonoBinaryReader reader)
284                 {
285                         Token = reader.ReadInt32 ();
286                         StartRow = reader.ReadInt32 ();
287                         EndRow = reader.ReadInt32 ();
288                         ThisTypeIndex = reader.ReadInt32 ();
289                         NumParameters = reader.ReadInt32 ();
290                         NumLocals = reader.ReadInt32 ();
291                         NumLineNumbers = reader.ReadInt32 ();
292                         TypeIndexTableOffset = reader.ReadInt32 ();
293                         LocalVariableTableOffset = reader.ReadInt32 ();
294                         SourceFileOffset = reader.ReadInt32 ();
295                         LineNumberTableOffset = reader.ReadInt32 ();
296
297                         if (SourceFileOffset != 0) {
298                                 long old_pos = reader.Position;
299                                 reader.Position = SourceFileOffset;
300                                 int source_file_length = reader.ReadInt32 ();
301                                 byte[] source_file = reader.ReadBuffer (source_file_length);
302                                 SourceFile = Encoding.UTF8.GetString (source_file);
303                                 reader.Position = old_pos;
304                         }
305
306                         if (LineNumberTableOffset != 0) {
307                                 long old_pos = reader.Position;
308                                 reader.Position = LineNumberTableOffset;
309
310                                 LineNumbers = new LineNumberEntry [NumLineNumbers];
311
312                                 for (int i = 0; i < NumLineNumbers; i++)
313                                         LineNumbers [i] = new LineNumberEntry (reader);
314
315                                 reader.Position = old_pos;
316                         }
317
318                         if (LocalVariableTableOffset != 0) {
319                                 long old_pos = reader.Position;
320                                 reader.Position = LocalVariableTableOffset;
321
322                                 Locals = new LocalVariableEntry [NumLocals];
323
324                                 for (int i = 0; i < NumLocals; i++)
325                                         Locals [i] = new LocalVariableEntry (reader);
326
327                                 reader.Position = old_pos;
328                         }
329
330                         if (TypeIndexTableOffset != 0) {
331                                 long old_pos = reader.Position;
332                                 reader.Position = TypeIndexTableOffset;
333
334                                 ParamTypeIndices = new int [NumParameters];
335                                 LocalTypeIndices = new int [NumLocals];
336
337                                 for (int i = 0; i < NumParameters; i++)
338                                         ParamTypeIndices [i] = reader.ReadInt32 ();
339                                 for (int i = 0; i < NumLocals; i++)
340                                         LocalTypeIndices [i] = reader.ReadInt32 ();
341
342                                 reader.Position = old_pos;
343                         }
344                 }
345
346                 internal MethodEntry (int token, int sf_offset, string source_file,
347                                       int this_type_index, int[] param_type_indices,
348                                       int[] local_type_indices, LocalVariableEntry[] locals,
349                                       LineNumberEntry[] lines, int lnt_offset,
350                                       int start_row, int end_row)
351                 {
352                         this.Token = token;
353                         this.StartRow = start_row;
354                         this.EndRow = end_row;
355                         this.NumLineNumbers = lines.Length;
356                         this.ThisTypeIndex = this_type_index;
357                         this.NumParameters = param_type_indices.Length;
358                         this.NumLocals = local_type_indices.Length;
359                         this.ParamTypeIndices = param_type_indices;
360                         this.LocalTypeIndices = local_type_indices;
361                         this.Locals = locals;
362                         this.SourceFileOffset = sf_offset;
363                         this.LineNumberTableOffset = lnt_offset;
364                         this.SourceFile = source_file;
365                         this.LineNumbers = lines;
366                 }
367
368                 internal void Write (BinaryWriter bw)
369                 {
370                         bw.Write (Token);
371                         bw.Write (StartRow);
372                         bw.Write (EndRow);
373                         bw.Write (ThisTypeIndex);
374                         bw.Write (NumParameters);
375                         bw.Write (NumLocals);
376                         bw.Write (NumLineNumbers);
377                         bw.Write (TypeIndexTableOffset);
378                         bw.Write (LocalVariableTableOffset);
379                         bw.Write (SourceFileOffset);
380                         bw.Write (LineNumberTableOffset);
381                 }
382
383                 public override string ToString ()
384                 {
385                         return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {5}:{6}]",
386                                               Token, SourceFile, StartRow, EndRow,
387                                               NumLineNumbers, SourceFileOffset, LineNumberTableOffset);
388                 }
389         }
390 }