public override ModuleDef?TryGetMetadata(DbgModule module, DbgLoadModuleOptions options) { if (module is null) { throw new ArgumentNullException(nameof(module)); } if (UseMemoryModules || module.IsDynamic || module.IsInMemory || (options & DbgLoadModuleOptions.ForceMemory) != 0) { return(dbgInMemoryModuleService.LoadModule(module)); } var mod = dbgInMemoryModuleService.FindModule(module); if (!(mod is null)) { return(mod); } var id = dbgModuleIdProviderService.GetModuleId(module); if (!(id is null)) { return(TryGetMetadata(id.Value, options)); } return(null); }
DbgLanguageDebugInfo CreateDebugInfo(IDbgDotNetCodeLocation location, CancellationToken cancellationToken) { const DbgLoadModuleOptions options = DbgLoadModuleOptions.AutoLoaded; ModuleDef mdModule; if (location.DbgModule is DbgModule dbgModule) { mdModule = dbgMetadataService.TryGetMetadata(dbgModule, options); } else { mdModule = dbgMetadataService.TryGetMetadata(location.Module, options); } Debug.Assert(mdModule != null); if (mdModule == null) { return(null); } cancellationToken.ThrowIfCancellationRequested(); var method = mdModule.ResolveToken(location.Token) as MethodDef; Debug.Assert(method != null); if (method == null) { return(null); } var context = new DecompilationContext { CancellationToken = cancellationToken, CalculateBinSpans = true, }; var output = DecompilerOutputImplCache.Alloc(); output.Initialize(method.MDToken.Raw); //TODO: Whenever the decompiler options change, we need to invalidate our cache and every // single DbgLanguageDebugInfo instance. decompiler.Decompile(method, output, context); var methodDebugInfo = output.TryGetMethodDebugInfo(); DecompilerOutputImplCache.Free(ref output); cancellationToken.ThrowIfCancellationRequested(); Debug.Assert(methodDebugInfo != null); if (methodDebugInfo == null) { return(null); } // We don't support EnC so the version is always 1 const int methodVersion = 1; return(new DbgLanguageDebugInfo(methodDebugInfo, methodVersion, location.Offset)); }
ModuleDef?LoadNonDiskFile(ModuleId moduleId, DbgLoadModuleOptions options) { if (UseMemoryModules || moduleId.IsDynamic || moduleId.IsInMemory || (options & DbgLoadModuleOptions.ForceMemory) != 0) { var module = dbgModuleIdProviderService.GetModule(moduleId); if (!(module is null)) { return(dbgInMemoryModuleService.LoadModule(module)); } } return(null); }
public override ModuleDef?TryGetMetadata(ModuleId moduleId, DbgLoadModuleOptions options) { var mod = LoadNonDiskFile(moduleId, options) ?? LoadExisting(moduleId); if (!(mod is null)) { return(mod); } if (moduleId.IsDynamic || moduleId.IsInMemory) { return(null); } string moduleFilename = moduleId.ModuleName; if (!File.Exists(moduleFilename)) { return(null); } var asmFilename = GetAssemblyFilename(moduleFilename, moduleId.AssemblyFullName, moduleId.ModuleNameOnly); bool isAutoLoaded = (options & DbgLoadModuleOptions.AutoLoaded) != 0; if (!string.IsNullOrEmpty(asmFilename)) { var document = documentService.TryGetOrCreate(DsDocumentInfo.CreateDocument(asmFilename), isAutoLoaded); if (document is null) { document = documentService.Resolve(new AssemblyNameInfo(moduleId.AssemblyFullName), null); } if (!(document is null)) { // Common case is a single-file assembly or first module of a multifile assembly if (asmFilename.Equals(moduleFilename, StringComparison.OrdinalIgnoreCase)) { return(document.ModuleDef); } foreach (var child in document.Children) { if (child.Filename.Equals(moduleFilename, StringComparison.OrdinalIgnoreCase)) { return(child.ModuleDef); } } } } return(documentService.TryGetOrCreate(DsDocumentInfo.CreateDocument(moduleFilename), isAutoLoaded)?.ModuleDef); }
ModuleDef LoadModule(DbgModule module, DbgLoadModuleOptions options, ref bool canShowMessageBox) { if (!module.IsDotNetModule()) { return(null); } if (module.IsDynamic && !module.Runtime.IsClosed && module.Process.IsRunning) { if (canShowMessageBox) { canShowMessageBox = false; messageBoxService.Value.Show(dnSpy_Debugger_DotNet_Resources.Module_BreakProcessBeforeLoadingDynamicModules); } return(null); } return(dbgMetadataService.Value.TryGetMetadata(module, options)); }
DbgLanguageDebugInfo CreateDebugInfo(DbgEvaluationContext context, IDbgDotNetCodeLocation location, CancellationToken cancellationToken) { const DbgLoadModuleOptions options = DbgLoadModuleOptions.AutoLoaded; ModuleDef mdModule; if (location.DbgModule is DbgModule dbgModule) { mdModule = dbgMetadataService.TryGetMetadata(dbgModule, options); } else { dbgModule = null; mdModule = dbgMetadataService.TryGetMetadata(location.Module, options); } Debug.Assert(mdModule != null); if (mdModule == null) { return(null); } cancellationToken.ThrowIfCancellationRequested(); var method = mdModule.ResolveToken(location.Token) as MethodDef; // Could be null if it's a dynamic assembly. It will get refreshed later and we'll get called again. if (method == null) { return(null); } var runtime = context.Runtime.GetDotNetRuntime(); int methodToken, localVarSigTok; if (dbgModule == null || !runtime.TryGetMethodToken(dbgModule, method.MDToken.ToInt32(), out methodToken, out localVarSigTok)) { methodToken = method.MDToken.ToInt32(); localVarSigTok = (int)(method.Body?.LocalVarSigTok ?? 0); } var decContext = new DecompilationContext { CancellationToken = cancellationToken, CalculateBinSpans = true, }; var output = DecompilerOutputImplCache.Alloc(); output.Initialize(method.MDToken.Raw); //TODO: Whenever the decompiler options change, we need to invalidate our cache and every // single DbgLanguageDebugInfo instance. decompiler.Decompile(method, output, decContext); var methodDebugInfo = output.TryGetMethodDebugInfo(); DecompilerOutputImplCache.Free(ref output); cancellationToken.ThrowIfCancellationRequested(); Debug.Assert(methodDebugInfo != null); if (methodDebugInfo == null) { return(null); } // We don't support EnC so the version is always 1 const int methodVersion = 1; return(new DbgLanguageDebugInfo(methodDebugInfo, methodToken, localVarSigTok, methodVersion, location.Offset)); }
/// <summary> /// Returns a <see cref="ModuleDef"/> or null if none could be loaded /// </summary> /// <param name="moduleId">Module id</param> /// <param name="options">Load options</param> /// <returns></returns> public abstract ModuleDef TryGetMetadata(ModuleId moduleId, DbgLoadModuleOptions options = DbgLoadModuleOptions.None);
/// <summary> /// Returns a <see cref="ModuleDef"/> or null if none could be loaded /// </summary> /// <param name="module">Module</param> /// <param name="options">Load options</param> /// <returns></returns> public abstract ModuleDef?TryGetMetadata(DbgModule module, DbgLoadModuleOptions options = DbgLoadModuleOptions.None);