2002-11-04 Stuart Caborn <stuart.caborn@clearswift.com>
[mono.git] / mcs / class / Mono.CSharp.Debugger / MonoSymbolTable.cs
index ee4cbd207d7a22b4c472563b64559a51b7a3b7e2..7692f6579fd5eea62e79b31c55d3cba860cba552 100644 (file)
@@ -18,26 +18,44 @@ namespace Mono.CSharp.Debugger
 {
        public struct OffsetTable
        {
-               public const uint Version = 16;
+               public const int  Version = 28;
                public const long Magic   = 0x45e82623fd7fa614;
 
-               public uint total_file_size;
-               public uint source_table_offset;
-               public uint source_table_size;
-               public uint method_table_offset;
-               public uint method_table_size;
-               public uint line_number_table_offset;
-               public uint line_number_table_size;
+               public int total_file_size;
+               public int source_table_offset;
+               public int source_table_size;
+               public int method_count;
+               public int method_table_offset;
+               public int method_table_size;
+               public int line_number_table_offset;
+               public int line_number_table_size;
+               public int local_variable_table_offset;
+               public int local_variable_table_size;
+               public int source_file_table_offset;
+               public int source_file_table_size;
+               public int source_file_count;
+               public int type_count;
+               public int type_index_table_offset;
+               public int type_index_table_size;
 
-               public OffsetTable (BinaryReader reader)
+               public OffsetTable (IMonoBinaryReader reader)
                {
-                       total_file_size = reader.ReadUInt32 ();
-                       source_table_offset = reader.ReadUInt32 ();
-                       source_table_size = reader.ReadUInt32 ();
-                       method_table_offset = reader.ReadUInt32 ();
-                       method_table_size = reader.ReadUInt32 ();
-                       line_number_table_offset = reader.ReadUInt32 ();
-                       line_number_table_size = reader.ReadUInt32 ();
+                       total_file_size = reader.ReadInt32 ();
+                       source_table_offset = reader.ReadInt32 ();
+                       source_table_size = reader.ReadInt32 ();
+                       method_count = reader.ReadInt32 ();
+                       method_table_offset = reader.ReadInt32 ();
+                       method_table_size = reader.ReadInt32 ();
+                       line_number_table_offset = reader.ReadInt32 ();
+                       line_number_table_size = reader.ReadInt32 ();
+                       local_variable_table_offset = reader.ReadInt32 ();
+                       local_variable_table_size = reader.ReadInt32 ();
+                       source_file_table_offset = reader.ReadInt32 ();
+                       source_file_table_size = reader.ReadInt32 ();
+                       source_file_count = reader.ReadInt32 ();
+                       type_count = reader.ReadInt32 ();
+                       type_index_table_offset = reader.ReadInt32 ();
+                       type_index_table_size = reader.ReadInt32 ();
                }
 
                public void Write (BinaryWriter bw)
@@ -45,126 +63,357 @@ namespace Mono.CSharp.Debugger
                        bw.Write (total_file_size);
                        bw.Write (source_table_offset);
                        bw.Write (source_table_size);
+                       bw.Write (method_count);
                        bw.Write (method_table_offset);
                        bw.Write (method_table_size);
                        bw.Write (line_number_table_offset);
                        bw.Write (line_number_table_size);
+                       bw.Write (local_variable_table_offset);
+                       bw.Write (local_variable_table_size);
+                       bw.Write (source_file_table_offset);
+                       bw.Write (source_file_table_size);
+                       bw.Write (source_file_count);
+                       bw.Write (type_count);
+                       bw.Write (type_index_table_offset);
+                       bw.Write (type_index_table_size);
                }
        }
 
        public struct LineNumberEntry
        {
-               public uint Row;
-               public uint Offset;
-               public uint Address;
+               public readonly int Row;
+               public readonly int Offset;
 
-               public static LineNumberEntry Null = new LineNumberEntry (0, 0);
-
-               public LineNumberEntry (uint row, uint offset)
+               public LineNumberEntry (int row, int offset)
                {
                        this.Row = row;
                        this.Offset = offset;
-                       this.Address = 0;
                }
 
-               public LineNumberEntry (ISourceLine line)
-                       : this ((uint) line.Row, (uint) line.Offset)
-               { }             
+               internal LineNumberEntry (SourceLine line)
+                       : this (line.Row, line.Offset)
+               { }
 
-               public LineNumberEntry (BinaryReader reader)
+               public LineNumberEntry (IMonoBinaryReader reader)
                {
-                       Row = reader.ReadUInt32 ();
-                       Offset = reader.ReadUInt32 ();
-                       Address = reader.ReadUInt32 ();
+                       Row = reader.ReadInt32 ();
+                       Offset = reader.ReadInt32 ();
                }
 
-               public bool IsNull {
+               internal void Write (BinaryWriter bw)
+               {
+                       bw.Write (Row);
+                       bw.Write (Offset);
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("[Line {0}:{1}]", Row, Offset);
+               }
+       }
+
+       public struct LocalVariableEntry
+       {
+               public readonly string Name;
+               public readonly FieldAttributes Attributes;
+               public readonly byte[] Signature;
+
+               public LocalVariableEntry (string Name, FieldAttributes Attributes, byte[] Signature)
+               {
+                       this.Name = Name;
+                       this.Attributes = Attributes;
+                       this.Signature = Signature;
+               }
+
+               public LocalVariableEntry (IMonoBinaryReader reader)
+               {
+                       int name_length = reader.ReadInt32 ();
+                       byte[] name = reader.ReadBuffer (name_length);
+                       Name = Encoding.UTF8.GetString (name);
+                       Attributes = (FieldAttributes) reader.ReadInt32 ();
+                       int sig_length = reader.ReadInt32 ();
+                       Signature = reader.ReadBuffer (sig_length);
+               }
+
+               internal void Write (BinaryWriter bw)
+               {
+                       byte[] name = Encoding.UTF8.GetBytes (Name);
+                       bw.Write ((int) name.Length);
+                       bw.Write (name);
+                       bw.Write ((int) Attributes);
+                       bw.Write ((int) Signature.Length);
+                       bw.Write (Signature);
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("[LocalVariable {0}:{1}]", Name, Attributes);
+               }
+       }
+
+       public class SourceFileEntry
+       {
+               public readonly string SourceFile;
+
+               IMonoBinaryReader reader;
+               long method_position;
+               ArrayList methods;
+               int count;
+
+               internal SourceFileEntry (string source_file)
+               {
+                       this.SourceFile = source_file;
+                       this.methods = new ArrayList ();
+                       this.count = 0;
+               }
+
+               internal void AddMethod (MethodSourceEntry method)
+               {
+                       methods.Add (method);
+                       count++;
+               }
+
+               internal void Write (BinaryWriter bw)
+               {
+                       byte[] name = Encoding.UTF8.GetBytes (SourceFile);
+                       bw.Write ((int) name.Length);
+                       bw.Write (name);
+
+                       methods.Sort ();
+                       bw.Write (methods.Count);
+                       foreach (MethodSourceEntry method in methods)
+                               method.Write (bw);
+               }
+
+               public SourceFileEntry (IMonoBinaryReader reader)
+               {
+                       int name_length = reader.ReadInt32 ();
+                       byte[] name = reader.ReadBuffer (name_length);
+                       SourceFile = Encoding.UTF8.GetString (name);
+
+                       count = reader.ReadInt32 ();
+                       this.reader = reader;
+                       this.method_position = reader.Position;
+
+                       reader.Position += count * MethodSourceEntry.Size;
+               }
+
+               public MethodSourceEntry[] Methods {
                        get {
-                               return Row == 0;
+                               read_methods ();
+                               MethodSourceEntry[] retval = new MethodSourceEntry [methods.Count];
+                               methods.CopyTo (retval, 0);
+                               return retval;
                        }
                }
 
-               public void Write (BinaryWriter bw)
+               void read_methods ()
                {
-                       bw.Write (Row);
-                       bw.Write (Offset);
-                       bw.Write (Address);
+                       if (methods != null)
+                               return;
+
+                       reader.Position = method_position;
+                       methods = new ArrayList ();
+                       for (int i = 0; i < count; i++)
+                               methods.Add (new MethodSourceEntry (reader));
                }
 
                public override string ToString ()
                {
-                       return String.Format ("[Line {0}:{1}:{2}]", Row, Offset, Address);
+                       return String.Format ("SourceFileEntry ({0}:{1})", SourceFile, count);
                }
        }
 
-       public struct MethodEntry
+       public struct MethodSourceEntry : IComparable
        {
-               public uint Token;
-               public uint SourceFileOffset;
-               public uint LineNumberTableOffset;
-               public uint StartRow;
-               public long StartAddress;
-               public long EndAddress;
+               public readonly int Index;
+               public readonly int FileOffset;
+               public readonly int StartRow;
+               public readonly int EndRow;
 
-               public readonly string SourceFile;
-               public readonly LineNumberEntry[] LineNumbers;
+               public MethodSourceEntry (int index, int file_offset, int start, int end)
+               {
+                       this.Index = index;
+                       this.FileOffset = file_offset;
+                       this.StartRow = start;
+                       this.EndRow = end;
+               }
+
+               public MethodSourceEntry (IMonoBinaryReader reader)
+               {
+                       Index = reader.ReadInt32 ();
+                       FileOffset = reader.ReadInt32 ();
+                       StartRow = reader.ReadInt32 ();
+                       EndRow = reader.ReadInt32 ();
+               }
+
+               public static int Size
+               {
+                       get {
+                               return 16;
+                       }
+               }
+
+               internal void Write (BinaryWriter bw)
+               {
+                       bw.Write (Index);
+                       bw.Write (FileOffset);
+                       bw.Write (StartRow);
+                       bw.Write (EndRow);
+               }
+
+               public int CompareTo (object obj)
+               {
+                       MethodSourceEntry method = (MethodSourceEntry) obj;
+
+                       if (method.StartRow < StartRow)
+                               return -1;
+                       else if (method.StartRow > StartRow)
+                               return 1;
+                       else
+                               return 0;
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("MethodSourceEntry ({0}:{1}:{2}:{3})",
+                                             Index, FileOffset, StartRow, EndRow);
+               }
+       }
+
+       public class MethodEntry
+       {
+               public readonly int Token;
+               public readonly int StartRow;
+               public readonly int EndRow;
+               public readonly int NumLineNumbers;
+               public readonly int ThisTypeIndex;
+               public readonly int NumParameters;
+               public readonly int NumLocals;
+
+               public int TypeIndexTableOffset;
+               public int LocalVariableTableOffset;
+               public readonly int SourceFileOffset;
+               public readonly int LineNumberTableOffset;
+
+               public readonly string SourceFile = null;
+               public readonly LineNumberEntry[] LineNumbers = null;
+               public readonly int[] ParamTypeIndices = null;
+               public readonly int[] LocalTypeIndices = null;
+               public readonly LocalVariableEntry[] Locals = null;
+
+               public static int Size
+               {
+                       get {
+                               return 44;
+                       }
+               }
 
-               public MethodEntry (BinaryReader reader)
+               public MethodEntry (IMonoBinaryReader reader)
                {
-                       Token = reader.ReadUInt32 ();
-                       SourceFileOffset = reader.ReadUInt32 ();
-                       LineNumberTableOffset = reader.ReadUInt32 ();
-                       StartRow = reader.ReadUInt32 ();
-                       StartAddress = reader.ReadInt64 ();
-                       EndAddress = reader.ReadInt64 ();
+                       Token = reader.ReadInt32 ();
+                       StartRow = reader.ReadInt32 ();
+                       EndRow = reader.ReadInt32 ();
+                       ThisTypeIndex = reader.ReadInt32 ();
+                       NumParameters = reader.ReadInt32 ();
+                       NumLocals = reader.ReadInt32 ();
+                       NumLineNumbers = reader.ReadInt32 ();
+                       TypeIndexTableOffset = reader.ReadInt32 ();
+                       LocalVariableTableOffset = reader.ReadInt32 ();
+                       SourceFileOffset = reader.ReadInt32 ();
+                       LineNumberTableOffset = reader.ReadInt32 ();
+
+                       if (SourceFileOffset != 0) {
+                               long old_pos = reader.Position;
+                               reader.Position = SourceFileOffset;
+                               int source_file_length = reader.ReadInt32 ();
+                               byte[] source_file = reader.ReadBuffer (source_file_length);
+                               SourceFile = Encoding.UTF8.GetString (source_file);
+                               reader.Position = old_pos;
+                       }
 
-                       long old_pos = reader.BaseStream.Position;
-                       reader.BaseStream.Position = LineNumberTableOffset;
+                       if (LineNumberTableOffset != 0) {
+                               long old_pos = reader.Position;
+                               reader.Position = LineNumberTableOffset;
 
-                       ArrayList lines = new ArrayList ();
+                               LineNumbers = new LineNumberEntry [NumLineNumbers];
 
-                       while (true) {
-                               LineNumberEntry lne = new LineNumberEntry (reader);
-                               if (lne.IsNull)
-                                       break;
-                               lines.Add (lne);
+                               for (int i = 0; i < NumLineNumbers; i++)
+                                       LineNumbers [i] = new LineNumberEntry (reader);
+
+                               reader.Position = old_pos;
+                       }
+
+                       if (LocalVariableTableOffset != 0) {
+                               long old_pos = reader.Position;
+                               reader.Position = LocalVariableTableOffset;
+
+                               Locals = new LocalVariableEntry [NumLocals];
+
+                               for (int i = 0; i < NumLocals; i++)
+                                       Locals [i] = new LocalVariableEntry (reader);
+
+                               reader.Position = old_pos;
                        }
 
-                       reader.BaseStream.Position = SourceFileOffset;
-                       SourceFile = reader.ReadString ();
-                       reader.BaseStream.Position = old_pos;
+                       if (TypeIndexTableOffset != 0) {
+                               long old_pos = reader.Position;
+                               reader.Position = TypeIndexTableOffset;
 
-                       LineNumbers = new LineNumberEntry [lines.Count];
-                       lines.CopyTo (LineNumbers);
+                               ParamTypeIndices = new int [NumParameters];
+                               LocalTypeIndices = new int [NumLocals];
+
+                               for (int i = 0; i < NumParameters; i++)
+                                       ParamTypeIndices [i] = reader.ReadInt32 ();
+                               for (int i = 0; i < NumLocals; i++)
+                                       LocalTypeIndices [i] = reader.ReadInt32 ();
+
+                               reader.Position = old_pos;
+                       }
                }
 
-               public MethodEntry (uint token, uint sf_offset, uint lnt_offset, uint row)
+               internal MethodEntry (int token, int sf_offset, string source_file,
+                                     int this_type_index, int[] param_type_indices,
+                                     int[] local_type_indices, LocalVariableEntry[] locals,
+                                     LineNumberEntry[] lines, int lnt_offset,
+                                     int start_row, int end_row)
                {
                        this.Token = token;
+                       this.StartRow = start_row;
+                       this.EndRow = end_row;
+                       this.NumLineNumbers = lines.Length;
+                       this.ThisTypeIndex = this_type_index;
+                       this.NumParameters = param_type_indices.Length;
+                       this.NumLocals = local_type_indices.Length;
+                       this.ParamTypeIndices = param_type_indices;
+                       this.LocalTypeIndices = local_type_indices;
+                       this.Locals = locals;
                        this.SourceFileOffset = sf_offset;
                        this.LineNumberTableOffset = lnt_offset;
-                       this.StartRow = row;
-                       this.StartAddress = 0;
-                       this.EndAddress = 0;
-                       this.SourceFile = null;
-                       this.LineNumbers = new LineNumberEntry [0];
+                       this.SourceFile = source_file;
+                       this.LineNumbers = lines;
                }
 
-               public void Write (BinaryWriter bw)
+               internal void Write (BinaryWriter bw)
                {
                        bw.Write (Token);
+                       bw.Write (StartRow);
+                       bw.Write (EndRow);
+                       bw.Write (ThisTypeIndex);
+                       bw.Write (NumParameters);
+                       bw.Write (NumLocals);
+                       bw.Write (NumLineNumbers);
+                       bw.Write (TypeIndexTableOffset);
+                       bw.Write (LocalVariableTableOffset);
                        bw.Write (SourceFileOffset);
                        bw.Write (LineNumberTableOffset);
-                       bw.Write (StartRow);
-                       bw.Write (StartAddress);
-                       bw.Write (EndAddress);
                }
 
                public override string ToString ()
                {
-                       return String.Format ("[Method {0}:{1}:{2}:{3}:{4}:{5}]",
-                                             Token, SourceFileOffset, LineNumberTableOffset,
-                                             StartRow, StartAddress, EndAddress);
+                       return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {5}:{6}]",
+                                             Token, SourceFile, StartRow, EndRow,
+                                             NumLineNumbers, SourceFileOffset, LineNumberTableOffset);
                }
        }
 }