using System; using System.Collections.Generic; using System.Data; using System.Data.SQLite; using System.Diagnostics.SymbolStore; using System.IO; using System.Linq; using System.Reflection; using Dapper; using DapperExtensions; using DapperExtensions.Mapper; using DapperExtensions.Sql; using Microsoft.Samples.Debugging.CorSymbolStore; using SQLinq; using SQLinq.Dapper; namespace Cosmos.Debug.Common { public class DebugInfo : IDisposable { /// /// Current id of the generation. /// private static long mLastGuid = 0; /// /// Range for the id generation process. /// private static long mPrefix = 0; /// /// Specifies range which is used by the assembler during compilation phase. /// public const long AssemblerDebugSymbolsRange = 0x0L; /// /// Specifies range which is used by the Elf map extraction process. /// public const long ElfFileMapExtractionRange = 0x1000000000000000L; /// /// Specifies range which is used by the Nasm map extraction process. /// public const long NAsmMapExtractionRange = 0x4000000000000000L; // Please beware this field, it may cause issues if used incorrectly. public static DebugInfo CurrentInstance { get; private set; } public class Field_Map { public string TypeName { get; set; } public List FieldNames = new List(); } protected SQLiteConnection mConnection; protected string mDbName; // Dont use DbConnectionStringBuilder class, it doesnt work with LocalDB properly. //protected mDataSouce = @".\SQLEXPRESS"; protected string mConnStr; public void DeleteDB(string aDbName, string aPathname) { File.Delete(aDbName); } public DebugInfo(string aPathname, bool aCreate = false, bool aCreateIndexes = false) { CurrentInstance = this; if (aCreate) { File.Delete(aPathname); } aCreate = !File.Exists(aPathname); // Manually register the data provider. Do not remove this otherwise the data provider doesn't register properly. mConnStr = String.Format("data source={0};journal mode=Memory;synchronous=Off;foreign keys=True;BinaryGuid=false", aPathname); // Use the SQLiteConnectionFactory as the default database connection // Do not open mConnection before mEntities.CreateDatabase mConnection = new SQLiteConnection(mConnStr); DapperExtensions.DapperExtensions.DefaultMapper = typeof(PluralizedAutoClassMapper<>); DapperExtensions.DapperExtensions.SqlDialect = new SqliteDialect(); if (aCreate) { // DatabaseExists checks if the DBName exists, not physical files. if (aCreate) { mConnection.Open(); var xSQL = new SQL(mConnection); xSQL.CreateDB(); // Be careful with indexes, they slow down inserts. So on tables that we have a // lot of inserts, but limited look ups, dont add them. // if (aCreateIndexes) { this.CreateIndexes(); } } } if (mConnection.State == ConnectionState.Closed) { mConnection.Open(); } } public IDbConnection Connection { get { return mConnection; } } /// /// Create indexes inside the database. /// public void CreateIndexes() { var xSQL = new SQL(mConnection); xSQL.MakeIndex("Labels", "Address", false); xSQL.MakeIndex("Labels", "Name", true); xSQL.MakeIndex("Methods", "DocumentID", false); xSQL.ExecuteAssemblyResource("SQLiteIndexes.sql"); } // The GUIDs etc are populated by the MSBuild task, so they wont be loaded when the debugger runs. // Because of this, we also allow manual loading. public void LoadLookups() { foreach (var xDoc in Connection.Query(new SQLinq().ToSQL().ToQuery())) { DocumentGUIDs.Add(xDoc.Pathname.ToLower(), xDoc.ID); } } public UInt32 AddressOfLabel(string aLabel) { var xRow = Connection.Query