2 // System.Diagnostics.SymbolStore/MonoSymbolTable.cs
5 // Martin Baulig (martin@gnome.org)
7 // (C) 2002 Ximian, Inc. http://www.ximian.com
11 using System.Reflection;
12 using System.Reflection.Emit;
13 using System.Collections;
17 namespace Mono.CSharp.Debugger
19 public struct OffsetTable
21 public const int Version = 29;
22 public const long Magic = 0x45e82623fd7fa614;
24 public int TotalFileSize;
25 public int DataSectionOffset;
26 public int DataSectionSize;
27 public int SourceCount;
28 public int SourceTableOffset;
29 public int SourceTableSize;
30 public int MethodCount;
31 public int MethodTableOffset;
32 public int MethodTableSize;
35 internal OffsetTable (BinaryReader reader)
37 TotalFileSize = reader.ReadInt32 ();
38 DataSectionOffset = reader.ReadInt32 ();
39 DataSectionSize = reader.ReadInt32 ();
40 SourceCount = reader.ReadInt32 ();
41 SourceTableOffset = reader.ReadInt32 ();
42 SourceTableSize = reader.ReadInt32 ();
43 MethodCount = reader.ReadInt32 ();
44 MethodTableOffset = reader.ReadInt32 ();
45 MethodTableSize = reader.ReadInt32 ();
46 TypeCount = reader.ReadInt32 ();
49 internal void Write (BinaryWriter bw)
51 bw.Write (TotalFileSize);
52 bw.Write (DataSectionOffset);
53 bw.Write (DataSectionSize);
54 bw.Write (SourceCount);
55 bw.Write (SourceTableOffset);
56 bw.Write (SourceTableSize);
57 bw.Write (MethodCount);
58 bw.Write (MethodTableOffset);
59 bw.Write (MethodTableSize);
64 public struct LineNumberEntry
66 public readonly int Row;
67 public readonly int Offset;
69 public LineNumberEntry (int row, int offset)
75 internal LineNumberEntry (SourceLine line)
76 : this (line.Row, line.Offset)
79 internal LineNumberEntry (BinaryReader reader)
81 Row = reader.ReadInt32 ();
82 Offset = reader.ReadInt32 ();
85 internal void Write (BinaryWriter bw)
91 public override string ToString ()
93 return String.Format ("[Line {0}:{1}]", Row, Offset);
97 public struct LocalVariableEntry
99 public readonly string Name;
100 public readonly FieldAttributes Attributes;
101 public readonly byte[] Signature;
103 public LocalVariableEntry (string Name, FieldAttributes Attributes, byte[] Signature)
106 this.Attributes = Attributes;
107 this.Signature = Signature;
110 internal LocalVariableEntry (BinaryReader reader)
112 int name_length = reader.ReadInt32 ();
113 byte[] name = reader.ReadBytes (name_length);
114 Name = Encoding.UTF8.GetString (name);
115 Attributes = (FieldAttributes) reader.ReadInt32 ();
116 int sig_length = reader.ReadInt32 ();
117 Signature = reader.ReadBytes (sig_length);
120 internal void Write (MonoSymbolFile file, BinaryWriter bw)
122 file.WriteString (bw, Name);
123 bw.Write ((int) Attributes);
124 bw.Write ((int) Signature.Length);
125 bw.Write (Signature);
128 public override string ToString ()
130 return String.Format ("[LocalVariable {0}:{1}]", Name, Attributes);
134 public class SourceFileEntry
139 int index, count, name_offset, method_offset;
142 internal static int Size {
146 internal SourceFileEntry (MonoSymbolFile file, string file_name, int index)
149 this.file_name = file_name;
153 methods = new ArrayList ();
156 public void DefineMethod (MethodBase method, int token, LocalVariableEntry[] locals,
157 LineNumberEntry[] lines, int start, int end)
160 throw new InvalidOperationException ();
162 MethodEntry entry = new MethodEntry (
163 file, this, method, token, locals, lines, start, end);
166 file.AddMethod (entry);
169 internal void WriteData (BinaryWriter bw)
171 name_offset = (int) bw.BaseStream.Position;
172 file.WriteString (bw, file_name);
174 ArrayList list = new ArrayList ();
175 foreach (MethodEntry entry in methods)
176 list.Add (entry.Write (file, bw));
180 method_offset = (int) bw.BaseStream.Position;
181 foreach (MethodSourceEntry method in list)
185 internal void Write (BinaryWriter bw)
189 bw.Write (name_offset);
190 bw.Write (method_offset);
193 internal SourceFileEntry (MonoSymbolFile file, BinaryReader reader)
197 index = reader.ReadInt32 ();
198 count = reader.ReadInt32 ();
199 name_offset = reader.ReadInt32 ();
200 method_offset = reader.ReadInt32 ();
202 file_name = file.ReadString (name_offset);
206 get { return index; }
209 public string FileName {
210 get { return file_name; }
213 public MethodSourceEntry[] Methods {
216 throw new InvalidOperationException ();
218 BinaryReader reader = file.BinaryReader;
219 int old_pos = (int) reader.BaseStream.Position;
221 reader.BaseStream.Position = method_offset;
222 ArrayList list = new ArrayList ();
223 for (int i = 0; i < count; i ++)
224 list.Add (new MethodSourceEntry (reader));
225 reader.BaseStream.Position = old_pos;
227 MethodSourceEntry[] retval = new MethodSourceEntry [count];
228 list.CopyTo (retval, 0);
233 public override string ToString ()
235 return String.Format ("SourceFileEntry ({0}:{1}:{2})", index, file_name, count);
239 public struct MethodSourceEntry : IComparable
241 public readonly int Index;
242 public readonly int FileOffset;
243 public readonly int StartRow;
244 public readonly int EndRow;
246 public MethodSourceEntry (int index, int file_offset, int start, int end)
249 this.FileOffset = file_offset;
250 this.StartRow = start;
254 internal MethodSourceEntry (BinaryReader reader)
256 Index = reader.ReadInt32 ();
257 FileOffset = reader.ReadInt32 ();
258 StartRow = reader.ReadInt32 ();
259 EndRow = reader.ReadInt32 ();
262 public static int Size
269 internal void Write (BinaryWriter bw)
272 bw.Write (FileOffset);
277 public int CompareTo (object obj)
279 MethodSourceEntry method = (MethodSourceEntry) obj;
281 if (method.StartRow < StartRow)
283 else if (method.StartRow > StartRow)
289 public override string ToString ()
291 return String.Format ("MethodSourceEntry ({0}:{1}:{2}:{3})",
292 Index, FileOffset, StartRow, EndRow);
296 public class MethodEntry
298 #region This is actually written to the symbol file
299 public readonly int SourceFileIndex;
300 public readonly int Token;
301 public readonly int StartRow;
302 public readonly int EndRow;
303 public readonly int ThisTypeIndex;
304 public readonly int NumParameters;
305 public readonly int NumLocals;
306 public readonly int NumLineNumbers;
310 int TypeIndexTableOffset;
311 int LocalVariableTableOffset;
312 int LineNumberTableOffset;
320 public readonly SourceFileEntry SourceFile;
321 public readonly LineNumberEntry[] LineNumbers;
322 public readonly int[] ParamTypeIndices;
323 public readonly int[] LocalTypeIndices;
324 public readonly LocalVariableEntry[] Locals;
326 public static int Size
337 public string FullName {
338 get { return full_name; }
341 internal MethodEntry (MonoSymbolFile file, BinaryReader reader)
343 SourceFileIndex = reader.ReadInt32 ();
344 Token = reader.ReadInt32 ();
345 StartRow = reader.ReadInt32 ();
346 EndRow = reader.ReadInt32 ();
347 ThisTypeIndex = reader.ReadInt32 ();
348 NumParameters = reader.ReadInt32 ();
349 NumLocals = reader.ReadInt32 ();
350 NumLineNumbers = reader.ReadInt32 ();
351 NameOffset = reader.ReadInt32 ();
352 FullNameOffset = reader.ReadInt32 ();
353 TypeIndexTableOffset = reader.ReadInt32 ();
354 LocalVariableTableOffset = reader.ReadInt32 ();
355 LineNumberTableOffset = reader.ReadInt32 ();
357 name = file.ReadString (NameOffset);
358 full_name = file.ReadString (FullNameOffset);
360 SourceFile = file.GetSourceFile (SourceFileIndex);
362 if (LineNumberTableOffset != 0) {
363 long old_pos = reader.BaseStream.Position;
364 reader.BaseStream.Position = LineNumberTableOffset;
366 LineNumbers = new LineNumberEntry [NumLineNumbers];
368 for (int i = 0; i < NumLineNumbers; i++)
369 LineNumbers [i] = new LineNumberEntry (reader);
371 reader.BaseStream.Position = old_pos;
374 if (LocalVariableTableOffset != 0) {
375 long old_pos = reader.BaseStream.Position;
376 reader.BaseStream.Position = LocalVariableTableOffset;
378 Locals = new LocalVariableEntry [NumLocals];
380 for (int i = 0; i < NumLocals; i++)
381 Locals [i] = new LocalVariableEntry (reader);
383 reader.BaseStream.Position = old_pos;
386 if (TypeIndexTableOffset != 0) {
387 long old_pos = reader.BaseStream.Position;
388 reader.BaseStream.Position = TypeIndexTableOffset;
390 ParamTypeIndices = new int [NumParameters];
391 LocalTypeIndices = new int [NumLocals];
393 for (int i = 0; i < NumParameters; i++)
394 ParamTypeIndices [i] = reader.ReadInt32 ();
395 for (int i = 0; i < NumLocals; i++)
396 LocalTypeIndices [i] = reader.ReadInt32 ();
398 reader.BaseStream.Position = old_pos;
402 internal MethodEntry (MonoSymbolFile file, SourceFileEntry source, MethodBase method,
403 int token, LocalVariableEntry[] locals, LineNumberEntry[] lines,
404 int start_row, int end_row)
406 index = file.GetNextMethodIndex ();
409 SourceFileIndex = source.Index;
411 StartRow = start_row;
414 NumLineNumbers = lines.Length;
417 ParameterInfo[] parameters = method.GetParameters ();
418 if (parameters == null)
419 parameters = new ParameterInfo [0];
421 StringBuilder sb = new StringBuilder ();
422 sb.Append (method.DeclaringType.FullName);
424 sb.Append (method.Name);
426 for (int i = 0; i < parameters.Length; i++) {
429 sb.Append (parameters [i].ParameterType.FullName);
434 full_name = sb.ToString ();
436 NumParameters = parameters.Length;
437 ParamTypeIndices = new int [NumParameters];
438 for (int i = 0; i < NumParameters; i++)
439 ParamTypeIndices [i] = file.DefineType (parameters [i].ParameterType);
441 NumLocals = locals.Length;
444 LocalTypeIndices = new int [NumLocals];
445 for (int i = 0; i < NumLocals; i++)
446 LocalTypeIndices [i] = file.GetNextTypeIndex ();
451 ThisTypeIndex = file.DefineType (method.ReflectedType);
454 internal MethodSourceEntry Write (MonoSymbolFile file, BinaryWriter bw)
456 NameOffset = (int) bw.BaseStream.Position;
457 file.WriteString (bw, name);
459 FullNameOffset = (int) bw.BaseStream.Position;
460 file.WriteString (bw, full_name);
462 TypeIndexTableOffset = (int) bw.BaseStream.Position;
464 for (int i = 0; i < NumParameters; i++)
465 bw.Write (ParamTypeIndices [i]);
466 for (int i = 0; i < NumLocals; i++)
467 bw.Write (LocalTypeIndices [i]);
469 LocalVariableTableOffset = (int) bw.BaseStream.Position;
471 for (int i = 0; i < NumLocals; i++)
472 Locals [i].Write (file, bw);
474 LineNumberTableOffset = (int) bw.BaseStream.Position;
476 for (int i = 0; i < NumLineNumbers; i++)
477 LineNumbers [i].Write (bw);
479 file_offset = (int) bw.BaseStream.Position;
481 bw.Write (SourceFileIndex);
485 bw.Write (ThisTypeIndex);
486 bw.Write (NumParameters);
487 bw.Write (NumLocals);
488 bw.Write (NumLineNumbers);
489 bw.Write (NameOffset);
490 bw.Write (FullNameOffset);
491 bw.Write (TypeIndexTableOffset);
492 bw.Write (LocalVariableTableOffset);
493 bw.Write (LineNumberTableOffset);
495 return new MethodSourceEntry (index, file_offset, StartRow, EndRow);
498 internal void WriteIndex (BinaryWriter bw)
500 bw.Write (file_offset);
501 bw.Write (FullNameOffset);
504 public override string ToString ()
506 return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {5} - {6}]",
507 SourceFileIndex, index, Token, StartRow, EndRow,
508 SourceFile, FullName);