X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FMono.CompilerServices.SymbolWriter%2FMonoSymbolTable.cs;h=277f25a7f6fade9f356f88b0795e82941db80e57;hb=9da5058deef9c3ce52cbc356b7a943e8dc4cd71a;hp=65b5998bf12c775cd017a0c4775340b6798bf3b0;hpb=3331634f37c395ea87d15a2f3338b2bc66a8470a;p=mono.git diff --git a/mcs/class/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs b/mcs/class/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs index 65b5998bf12..277f25a7f6f 100644 --- a/mcs/class/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs +++ b/mcs/class/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs @@ -30,7 +30,7 @@ using System; using System.Security.Cryptography; -using System.Collections; +using System.Collections.Generic; using System.Text; using System.IO; @@ -183,63 +183,56 @@ namespace Mono.CompilerServices.SymbolWriter { #region This is actually written to the symbol file public readonly int Row; + public int Column; + public int EndRow, EndColumn; public readonly int File; public readonly int Offset; - public readonly bool IsHidden; + public readonly bool IsHidden; // Obsolete is never used #endregion - public LineNumberEntry (int file, int row, int offset) - : this (file, row, offset, false) - { } - - public LineNumberEntry (int file, int row, int offset, bool is_hidden) + public sealed class LocationComparer : IComparer { - this.File = file; - this.Row = row; - this.Offset = offset; - this.IsHidden = is_hidden; + public static readonly LocationComparer Default = new LocationComparer (); + + public int Compare (LineNumberEntry l1, LineNumberEntry l2) + { + return l1.Row == l2.Row ? + l1.Column.CompareTo (l2.Column) : + l1.Row.CompareTo (l2.Row); + } } - public static LineNumberEntry Null = new LineNumberEntry (0, 0, 0); + public static readonly LineNumberEntry Null = new LineNumberEntry (0, 0, 0, 0); - private class OffsetComparerClass : IComparer + public LineNumberEntry (int file, int row, int column, int offset) + : this (file, row, offset, column, false) { - public int Compare (object a, object b) - { - LineNumberEntry l1 = (LineNumberEntry) a; - LineNumberEntry l2 = (LineNumberEntry) b; - - if (l1.Offset < l2.Offset) - return -1; - else if (l1.Offset > l2.Offset) - return 1; - else - return 0; - } } - private class RowComparerClass : IComparer + public LineNumberEntry (int file, int row, int offset) + : this (file, row, -1, offset, false) + { + } + + public LineNumberEntry (int file, int row, int column, int offset, bool is_hidden) + : this (file, row, column, -1, -1, offset, is_hidden) { - public int Compare (object a, object b) - { - LineNumberEntry l1 = (LineNumberEntry) a; - LineNumberEntry l2 = (LineNumberEntry) b; - - if (l1.Row < l2.Row) - return -1; - else if (l1.Row > l2.Row) - return 1; - else - return 0; - } } - public static readonly IComparer OffsetComparer = new OffsetComparerClass (); - public static readonly IComparer RowComparer = new RowComparerClass (); + public LineNumberEntry (int file, int row, int column, int end_row, int end_column, int offset, bool is_hidden) + { + this.File = file; + this.Row = row; + this.Column = column; + this.EndRow = end_row; + this.EndColumn = end_column; + this.Offset = offset; + this.IsHidden = is_hidden; + } public override string ToString () { - return String.Format ("[Line {0}:{1}:{2}]", File, Row, Offset); + return String.Format ("[Line {0}:{1,2}-{3,4}:{5}]", File, Row, Column, EndRow, EndColumn, Offset); } } @@ -336,7 +329,7 @@ namespace Mono.CompilerServices.SymbolWriter public override string ToString () { return String.Format ("[LocalVariable {0}:{1}:{2}]", - Name, Index, BlockIndex); + Name, Index, BlockIndex - 1); } } @@ -453,8 +446,8 @@ namespace Mono.CompilerServices.SymbolWriter public readonly int ID; #endregion - ArrayList captured_vars = new ArrayList (); - ArrayList captured_scopes = new ArrayList (); + List captured_vars = new List (); + List captured_scopes = new List (); public AnonymousScopeEntry (int id) { @@ -529,8 +522,8 @@ namespace Mono.CompilerServices.SymbolWriter MonoSymbolFile file; SourceFileEntry source; - ArrayList include_files; - ArrayList namespaces; + List include_files; + List namespaces; bool creating; @@ -550,7 +543,7 @@ namespace Mono.CompilerServices.SymbolWriter this.Index = file.AddCompileUnit (this); creating = true; - namespaces = new ArrayList (); + namespaces = new List (); } public void AddFile (SourceFileEntry file) @@ -559,7 +552,7 @@ namespace Mono.CompilerServices.SymbolWriter throw new InvalidOperationException (); if (include_files == null) - include_files = new ArrayList (); + include_files = new List (); include_files.Add (file); } @@ -616,6 +609,11 @@ namespace Mono.CompilerServices.SymbolWriter DataOffset = reader.ReadInt32 (); } + public void ReadAll () + { + ReadData (); + } + void ReadData () { if (creating) @@ -635,15 +633,13 @@ namespace Mono.CompilerServices.SymbolWriter int count_includes = reader.ReadLeb128 (); if (count_includes > 0) { - include_files = new ArrayList (); - for (int i = 0; i < count_includes; i++) { - // FIXME: The debugger will need this later on. - reader.ReadLeb128 (); - } + include_files = new List (); + for (int i = 0; i < count_includes; i++) + include_files.Add (file.GetSourceFile (reader.ReadLeb128 ())); } int count_ns = reader.ReadLeb128 (); - namespaces = new ArrayList (); + namespaces = new List (); for (int i = 0; i < count_ns; i ++) namespaces.Add (new NamespaceEntry (file, reader)); @@ -659,6 +655,18 @@ namespace Mono.CompilerServices.SymbolWriter return retval; } } + + public SourceFileEntry[] IncludeFiles { + get { + ReadData (); + if (include_files == null) + return new SourceFileEntry [0]; + + SourceFileEntry[] retval = new SourceFileEntry [include_files.Count]; + include_files.CopyTo (retval, 0); + return retval; + } + } } public class SourceFileEntry @@ -688,26 +696,33 @@ namespace Mono.CompilerServices.SymbolWriter creating = true; } - public SourceFileEntry (MonoSymbolFile file, string file_name, - byte[] guid, byte[] checksum) + public SourceFileEntry (MonoSymbolFile file, string file_name, byte[] guid, byte[] checksum) : this (file, file_name) { this.guid = guid; this.hash = checksum; } + public byte[] Checksum { + get { + return hash; + } + } + internal void WriteData (MyBinaryWriter bw) { DataOffset = (int) bw.BaseStream.Position; bw.Write (file_name); - if (guid == null) { - guid = Guid.NewGuid ().ToByteArray (); + if (guid == null) + guid = new byte[16]; + + if (hash == null) { try { - using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) { - MD5 md5 = MD5.Create (); - hash = md5.ComputeHash (fs); - } + using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) { + MD5 md5 = MD5.Create (); + hash = md5.ComputeHash (fs); + } } catch { hash = new byte [16]; } @@ -744,6 +759,7 @@ namespace Mono.CompilerServices.SymbolWriter public string FileName { get { return file_name; } + set { file_name = value; } } public bool AutoGenerated { @@ -798,7 +814,6 @@ namespace Mono.CompilerServices.SymbolWriter public const int Default_LineRange = 8; public const byte Default_OpcodeBase = 9; - public const bool SuppressDuplicates = true; #endregion public const byte DW_LNS_copy = 1; @@ -812,6 +827,9 @@ namespace Mono.CompilerServices.SymbolWriter // MONO extensions. public const byte DW_LNE_MONO_negate_is_hidden = 0x40; + internal const byte DW_LNE_MONO__extensions_start = 0x40; + internal const byte DW_LNE_MONO__extensions_end = 0x7f; + protected LineNumberTable (MonoSymbolFile file) { this.LineBase = file.OffsetTable.LineNumberTable_LineBase; @@ -826,7 +844,7 @@ namespace Mono.CompilerServices.SymbolWriter this._line_numbers = lines; } - internal void Write (MonoSymbolFile file, MyBinaryWriter bw) + internal void Write (MonoSymbolFile file, MyBinaryWriter bw, bool hasColumnsInfo, bool hasEndInfo) { int start = (int) bw.BaseStream.Position; @@ -836,11 +854,6 @@ namespace Mono.CompilerServices.SymbolWriter int line_inc = LineNumbers [i].Row - last_line; int offset_inc = LineNumbers [i].Offset - last_offset; - if (SuppressDuplicates && (i+1 < LineNumbers.Length)) { - if (LineNumbers [i+1].Equals (LineNumbers [i])) - continue; - } - if (LineNumbers [i].File != last_file) { bw.Write (DW_LNS_set_file); bw.WriteLeb128 (LineNumbers [i].File); @@ -888,19 +901,39 @@ namespace Mono.CompilerServices.SymbolWriter bw.Write ((byte) 1); bw.Write (DW_LNE_end_sequence); + if (hasColumnsInfo) { + for (int i = 0; i < LineNumbers.Length; i++) { + var ln = LineNumbers [i]; + if (ln.Row >= 0) + bw.WriteLeb128 (ln.Column); + } + } + + if (hasEndInfo) { + for (int i = 0; i < LineNumbers.Length; i++) { + var ln = LineNumbers [i]; + if (ln.EndRow == -1 || ln.EndColumn == -1 || ln.Row > ln.EndRow) { + bw.WriteLeb128 (0xffffff); + } else { + bw.WriteLeb128 (ln.EndRow - ln.Row); + bw.WriteLeb128 (ln.EndColumn); + } + } + } + file.ExtendedLineNumberSize += (int) bw.BaseStream.Position - start; } - internal static LineNumberTable Read (MonoSymbolFile file, MyBinaryReader br) + internal static LineNumberTable Read (MonoSymbolFile file, MyBinaryReader br, bool readColumnsInfo, bool readEndInfo) { LineNumberTable lnt = new LineNumberTable (file); - lnt.DoRead (file, br); + lnt.DoRead (file, br, readColumnsInfo, readEndInfo); return lnt; } - void DoRead (MonoSymbolFile file, MyBinaryReader br) + void DoRead (MonoSymbolFile file, MyBinaryReader br, bool includesColumns, bool includesEnds) { - ArrayList lines = new ArrayList (); + var lines = new List (); bool is_hidden = false, modified = false; int stm_line = 1, stm_offset = 0, stm_file = 1; @@ -915,15 +948,17 @@ namespace Mono.CompilerServices.SymbolWriter if (opcode == DW_LNE_end_sequence) { if (modified) lines.Add (new LineNumberEntry ( - stm_file, stm_line, stm_offset, is_hidden)); + stm_file, stm_line, -1, stm_offset, is_hidden)); break; } else if (opcode == DW_LNE_MONO_negate_is_hidden) { is_hidden = !is_hidden; modified = true; - } else - throw new MonoSymbolFileException ( - "Unknown extended opcode {0:x} in LNT ({1})", - opcode, file.FileName); + } else if ((opcode >= DW_LNE_MONO__extensions_start) && + (opcode <= DW_LNE_MONO__extensions_end)) { + ; // reserved for future extensions + } else { + throw new MonoSymbolFileException ("Unknown extended opcode {0:x}", opcode); + } br.BaseStream.Position = end_pos; continue; @@ -931,7 +966,7 @@ namespace Mono.CompilerServices.SymbolWriter switch (opcode) { case DW_LNS_copy: lines.Add (new LineNumberEntry ( - stm_file, stm_line, stm_offset, is_hidden)); + stm_file, stm_line, -1, stm_offset, is_hidden)); modified = false; break; case DW_LNS_advance_pc: @@ -961,13 +996,34 @@ namespace Mono.CompilerServices.SymbolWriter stm_offset += opcode / LineRange; stm_line += LineBase + (opcode % LineRange); lines.Add (new LineNumberEntry ( - stm_file, stm_line, stm_offset, is_hidden)); + stm_file, stm_line, -1, stm_offset, is_hidden)); modified = false; } } - _line_numbers = new LineNumberEntry [lines.Count]; - lines.CopyTo (_line_numbers, 0); + _line_numbers = lines.ToArray (); + + if (includesColumns) { + for (int i = 0; i < _line_numbers.Length; ++i) { + var ln = _line_numbers[i]; + if (ln.Row >= 0) + ln.Column = br.ReadLeb128 (); + } + } + if (includesEnds) { + for (int i = 0; i < _line_numbers.Length; ++i) { + var ln = _line_numbers[i]; + + int row = br.ReadLeb128 (); + if (row == 0xffffff) { + ln.EndRow = -1; + ln.EndColumn = -1; + } else { + ln.EndRow = ln.Row + row; + ln.EndColumn = br.ReadLeb128 (); + } + } + } } public bool GetMethodBounds (out LineNumberEntry start, out LineNumberEntry end) @@ -1024,7 +1080,9 @@ namespace Mono.CompilerServices.SymbolWriter [Flags] public enum Flags { - LocalNamesAmbiguous = 1 + LocalNamesAmbiguous = 1, + ColumnsInfoIncluded = 1 << 1, + EndInfoIncluded = 1 << 2 } public const int Size = 12; @@ -1101,9 +1159,9 @@ namespace Mono.CompilerServices.SymbolWriter locals_check_done : ; } else { - Hashtable local_names = new Hashtable (); + var local_names = new Dictionary (); foreach (LocalVariableEntry local in locals) { - if (local_names.Contains (local.Name)) { + if (local_names.ContainsKey (local.Name)) { flags |= Flags.LocalNamesAmbiguous; break; } @@ -1112,7 +1170,7 @@ namespace Mono.CompilerServices.SymbolWriter } } - void CheckLineNumberTable (LineNumberEntry[] line_numbers) + static void CheckLineNumberTable (LineNumberEntry[] line_numbers) { int last_offset = -1; int last_row = -1; @@ -1177,8 +1235,13 @@ namespace Mono.CompilerServices.SymbolWriter bw.Write (real_name); } + foreach (var lne in lnt.LineNumbers) { + if (lne.EndRow != -1 || lne.EndColumn != -1) + flags |= Flags.EndInfoIncluded; + } + LineNumberTableOffset = (int) bw.BaseStream.Position; - lnt.Write (file, bw); + lnt.Write (file, bw, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); DataOffset = (int) bw.BaseStream.Position; @@ -1193,6 +1256,15 @@ namespace Mono.CompilerServices.SymbolWriter bw.WriteLeb128 ((int) flags); } + public void ReadAll () + { + GetLineNumberTable (); + GetLocals (); + GetCodeBlocks (); + GetScopeVariables (); + GetRealName (); + } + public LineNumberTable GetLineNumberTable () { lock (SymbolFile) { @@ -1206,7 +1278,7 @@ namespace Mono.CompilerServices.SymbolWriter long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = LineNumberTableOffset; - lnt = LineNumberTable.Read (SymbolFile, reader); + lnt = LineNumberTable.Read (SymbolFile, reader, (flags & Flags.ColumnsInfoIncluded) != 0, (flags & Flags.EndInfoIncluded) != 0); reader.BaseStream.Position = old_pos; return lnt;