📄 monosymboltable.cs
字号:
//// Mono.CSharp.Debugger/MonoSymbolTable.cs//// Author:// Martin Baulig (martin@ximian.com)//// (C) 2002 Ximian, Inc. http://www.ximian.com////// Permission is hereby granted, free of charge, to any person obtaining// a copy of this software and associated documentation files (the// "Software"), to deal in the Software without restriction, including// without limitation the rights to use, copy, modify, merge, publish,// distribute, sublicense, and/or sell copies of the Software, and to// permit persons to whom the Software is furnished to do so, subject to// the following conditions:// // The above copyright notice and this permission notice shall be// included in all copies or substantial portions of the Software.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.//using System;using System.Collections;using System.Text;using System.IO;//// Parts which are actually written into the symbol file are marked with//// #region This is actually written to the symbol file// #endregion//// Please do not modify these regions without previously talking to me.//// All changes to the file format must be synchronized in several places://// a) The fields in these regions (and their order) must match the actual// contents of the symbol file.//// This helps people to understand the symbol file format without reading// too much source code, ie. you look at the appropriate region and then// you know what's actually in the file.//// It is also required to help me enforce b).//// b) The regions must be kept in sync with the unmanaged code in// mono/metadata/debug-mono-symfile.h//// When making changes to the file format, you must also increase two version// numbers://// i) OffsetTable.Version in this file.// ii) MONO_SYMBOL_FILE_VERSION in mono/metadata/debug-mono-symfile.h//// After doing so, recompile everything, including the debugger. Symbol files// with different versions are incompatible to each other and the debugger and// the runtime enfore this, so you need to recompile all your assemblies after// changing the file format.//namespace Mono.CompilerServices.SymbolWriter{ public struct OffsetTable { public const int Version = 39; public const long Magic = 0x45e82623fd7fa614; #region This is actually written to the symbol file public int TotalFileSize; public int DataSectionOffset; public int DataSectionSize; public int SourceCount; public int SourceTableOffset; public int SourceTableSize; public int MethodCount; public int MethodTableOffset; public int MethodTableSize; public int TypeCount; #endregion internal OffsetTable (BinaryReader reader) { TotalFileSize = reader.ReadInt32 (); DataSectionOffset = reader.ReadInt32 (); DataSectionSize = reader.ReadInt32 (); SourceCount = reader.ReadInt32 (); SourceTableOffset = reader.ReadInt32 (); SourceTableSize = reader.ReadInt32 (); MethodCount = reader.ReadInt32 (); MethodTableOffset = reader.ReadInt32 (); MethodTableSize = reader.ReadInt32 (); TypeCount = reader.ReadInt32 (); } internal void Write (BinaryWriter bw) { bw.Write (TotalFileSize); bw.Write (DataSectionOffset); bw.Write (DataSectionSize); bw.Write (SourceCount); bw.Write (SourceTableOffset); bw.Write (SourceTableSize); bw.Write (MethodCount); bw.Write (MethodTableOffset); bw.Write (MethodTableSize); bw.Write (TypeCount); } public override string ToString () { return String.Format ( "OffsetTable [{0} - {1}:{2} - {3}:{4}:{5} - {6}:{7}:{8} - {9}]", TotalFileSize, DataSectionOffset, DataSectionSize, SourceCount, SourceTableOffset, SourceTableSize, MethodCount, MethodTableOffset, MethodTableSize, TypeCount); } } public struct LineNumberEntry { #region This is actually written to the symbol file public readonly int Row; public readonly int Offset; #endregion public LineNumberEntry (int row, int offset) { this.Row = row; this.Offset = offset; } public static LineNumberEntry Null = new LineNumberEntry (0, 0); internal LineNumberEntry (BinaryReader reader) { Row = reader.ReadInt32 (); Offset = reader.ReadInt32 (); } internal void Write (BinaryWriter bw) { bw.Write (Row); bw.Write (Offset); } private class OffsetComparerClass : IComparer { 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 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 override string ToString () { return String.Format ("[Line {0}:{1}]", Row, Offset); } } public class LexicalBlockEntry { public int Index; #region This is actually written to the symbol file public int StartOffset; public int EndOffset; #endregion public LexicalBlockEntry (int index, int start_offset) { this.Index = index; this.StartOffset = start_offset; } internal LexicalBlockEntry (int index, MyBinaryReader reader) { this.Index = index; this.StartOffset = reader.ReadInt32 (); this.EndOffset = reader.ReadInt32 (); } public void Close (int end_offset) { this.EndOffset = end_offset; } internal void Write (MyBinaryWriter bw) { bw.Write (StartOffset); bw.Write (EndOffset); } public override string ToString () { return String.Format ("[LexicalBlock {0}:{1}]", StartOffset, EndOffset); } } public struct LocalVariableEntry { #region This is actually written to the symbol file public readonly int Index; public readonly string Name; public readonly byte[] Signature; public readonly int BlockIndex; #endregion public LocalVariableEntry (int Index, string Name, byte[] Signature, int BlockIndex) { this.Index = Index; this.Name = Name; this.Signature = Signature; this.BlockIndex = BlockIndex; } internal LocalVariableEntry (MyBinaryReader reader) { Index = reader.ReadLeb128 (); Name = reader.ReadString (); int sig_length = reader.ReadLeb128 (); Signature = reader.ReadBytes (sig_length); BlockIndex = reader.ReadLeb128 (); } internal void Write (MonoSymbolFile file, MyBinaryWriter bw) { bw.WriteLeb128 (Index); bw.Write (Name); bw.WriteLeb128 ((int) Signature.Length); bw.Write (Signature); bw.WriteLeb128 (BlockIndex); } public override string ToString () { return String.Format ("[LocalVariable {0}]", Name); } } public class SourceFileEntry { #region This is actually written to the symbol file public readonly int Index; int Count; int NamespaceCount; int NameOffset; int MethodOffset; int NamespaceTableOffset; #endregion MonoSymbolFile file; string file_name; ArrayList methods; ArrayList namespaces; bool creating; public static int Size { get { return 24; } } public SourceFileEntry (MonoSymbolFile file, string file_name) { this.file = file; this.file_name = file_name; this.Index = file.AddSource (this); creating = true; methods = new ArrayList (); namespaces = new ArrayList (); } public void DefineMethod (string name, int token, LocalVariableEntry[] locals, LineNumberEntry[] lines, LexicalBlockEntry[] blocks, int start, int end, int namespace_id) { if (!creating) throw new InvalidOperationException (); MethodEntry entry = new MethodEntry ( file, this, name, (int) token, locals, lines, blocks, start, end, namespace_id); methods.Add (entry); file.AddMethod (entry); } public int DefineNamespace (string name, string[] using_clauses, int parent) { if (!creating) throw new InvalidOperationException (); int index = file.GetNextNamespaceIndex (); NamespaceEntry ns = new NamespaceEntry (name, index, using_clauses, parent); namespaces.Add (ns); return index; } internal void WriteData (MyBinaryWriter bw) { NameOffset = (int) bw.BaseStream.Position; bw.Write (file_name); ArrayList list = new ArrayList (); foreach (MethodEntry entry in methods) list.Add (entry.Write (file, bw)); list.Sort (); Count = list.Count; MethodOffset = (int) bw.BaseStream.Position; foreach (MethodSourceEntry method in list) method.Write (bw); NamespaceCount = namespaces.Count; NamespaceTableOffset = (int) bw.BaseStream.Position; foreach (NamespaceEntry ns in namespaces) ns.Write (file, bw); } internal void Write (BinaryWriter bw) { bw.Write (Index); bw.Write (Count); bw.Write (NamespaceCount); bw.Write (NameOffset); bw.Write (MethodOffset); bw.Write (NamespaceTableOffset); } internal SourceFileEntry (MonoSymbolFile file, BinaryReader reader) { this.file = file; Index = reader.ReadInt32 (); Count = reader.ReadInt32 (); NamespaceCount = reader.ReadInt32 (); NameOffset = reader.ReadInt32 (); MethodOffset = reader.ReadInt32 (); NamespaceTableOffset = reader.ReadInt32 (); file_name = file.ReadString (NameOffset); } public string FileName { get { return file_name; } } public MethodSourceEntry[] Methods { get { if (creating) throw new InvalidOperationException (); BinaryReader reader = file.BinaryReader; int old_pos = (int) reader.BaseStream.Position; reader.BaseStream.Position = MethodOffset; ArrayList list = new ArrayList (); for (int i = 0; i < Count; i ++) list.Add (new MethodSourceEntry (reader)); reader.BaseStream.Position = old_pos; MethodSourceEntry[] retval = new MethodSourceEntry [Count]; list.CopyTo (retval, 0); return retval; } } public NamespaceEntry[] Namespaces { get { if (creating) throw new InvalidOperationException (); MyBinaryReader reader = file.BinaryReader; int old_pos = (int) reader.BaseStream.Position; reader.BaseStream.Position = NamespaceTableOffset; ArrayList list = new ArrayList (); for (int i = 0; i < NamespaceCount; i ++) list.Add (new NamespaceEntry (file, reader)); reader.BaseStream.Position = old_pos; NamespaceEntry[] retval = new NamespaceEntry [list.Count]; list.CopyTo (retval, 0); return retval; } } public override string ToString () { return String.Format ("SourceFileEntry ({0}:{1}:{2})", Index, file_name, Count); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -