diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractRegistry.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractRegistry.cs index 5f4e5a6a85ce11..ddd8c9e2ff9d53 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractRegistry.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractRegistry.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using Microsoft.Diagnostics.DataContractReader.Contracts; @@ -117,6 +118,13 @@ public abstract class ContractRegistry public abstract TContract GetContract() where TContract : IContract; + /// + /// Register a contract implementation for a specific version. + /// External packages use this to add contract versions or entirely new contract interfaces. + /// + public abstract void Register(int version, Func creator) + where TContract : IContract; + /// /// Flush all cached data held by contracts in this registry. /// Called when the target process state may have changed (e.g. on resume). diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/AuxiliarySymbolsFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/AuxiliarySymbolsFactory.cs deleted file mode 100644 index 10faa7c9e7f028..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/AuxiliarySymbolsFactory.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class AuxiliarySymbolsFactory : IContractFactory -{ - IAuxiliarySymbols IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new AuxiliarySymbols_1(target), - _ => default(AuxiliarySymbols), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/BuiltInCOMFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/BuiltInCOMFactory.cs deleted file mode 100644 index f65056f6205b85..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/BuiltInCOMFactory.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class BuiltInCOMFactory : IContractFactory -{ - IBuiltInCOM IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new BuiltInCOM_1(target), - _ => default(BuiltInCOM), - }; - } - -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/CodeVersionsFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/CodeVersionsFactory.cs deleted file mode 100644 index 733bc5d5c0cf58..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/CodeVersionsFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class CodeVersionsFactory : IContractFactory -{ - ICodeVersions IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new CodeVersions_1(target), - _ => default(CodeVersions), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappersFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappersFactory.cs deleted file mode 100644 index c5de208863b0df..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ComWrappersFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class ComWrappersFactory : IContractFactory -{ - IComWrappers IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new ComWrappers_1(target), - _ => default(ComWrappers), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ConditionalWeakTableFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ConditionalWeakTableFactory.cs deleted file mode 100644 index f1c17dd3ec8561..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ConditionalWeakTableFactory.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class ConditionalWeakTableFactory : IContractFactory -{ - IConditionalWeakTable IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new ConditionalWeakTable_1(target), - _ => default(ConditionalWeakTable), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreamsFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreamsFactory.cs deleted file mode 100644 index dba47e0ec676a1..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreamsFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class DacStreamsFactory : IContractFactory -{ - IDacStreams IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new DacStreams_1(target), - _ => default(DacStreams), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebugInfo/DebugInfoFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebugInfo/DebugInfoFactory.cs deleted file mode 100644 index faf6028a641da8..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebugInfo/DebugInfoFactory.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class DebugInfoFactory : IContractFactory -{ - IDebugInfo IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new DebugInfo_1(target), - 2 => new DebugInfo_2(target), - _ => default(DebugInfo), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebuggerFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebuggerFactory.cs deleted file mode 100644 index 58bd60ac94c5c7..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DebuggerFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class DebuggerFactory : IContractFactory -{ - IDebugger IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new Debugger_1(target), - _ => default(Debugger), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadataFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadataFactory.cs deleted file mode 100644 index a628ae62ecca20..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadataFactory.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Reflection.Metadata; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class EcmaMetadataFactory : IContractFactory -{ - IEcmaMetadata IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new EcmaMetadata_1(target), - _ => default(EcmaMetadata), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExceptionFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExceptionFactory.cs deleted file mode 100644 index ec7016fd43a88c..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExceptionFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class ExceptionFactory : IContractFactory -{ - IException IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new Exception_1(target), - _ => default(Exception), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerFactory.cs deleted file mode 100644 index fa54c578a86639..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManagerFactory.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class ExecutionManagerFactory : IContractFactory -{ - IExecutionManager IContractFactory.CreateContract(Target target, int version) - { - TargetPointer executionManagerCodeRangeMapAddress = target.ReadGlobalPointer(Constants.Globals.ExecutionManagerCodeRangeMapAddress); - Data.RangeSectionMap rangeSectionMap = target.ProcessedData.GetOrAdd(executionManagerCodeRangeMapAddress); - return version switch - { - 1 => new ExecutionManager_1(target, rangeSectionMap), - - // The nibblemap algorithm was changed in version 2 - 2 => new ExecutionManager_2(target, rangeSectionMap), - _ => default(ExecutionManager), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_1.cs index e7c274cd41383a..b636a2914c36ec 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_1.cs @@ -10,9 +10,11 @@ public sealed class ExecutionManager_1 : IExecutionManager { private IExecutionManager _executionManagerCore; - internal ExecutionManager_1(Target target, Data.RangeSectionMap topRangeSectionMap) + internal ExecutionManager_1(Target target) { - _executionManagerCore = new ExecutionManagerCore(target, topRangeSectionMap); + TargetPointer addr = target.ReadGlobalPointer(Constants.Globals.ExecutionManagerCodeRangeMapAddress); + Data.RangeSectionMap map = target.ProcessedData.GetOrAdd(addr); + _executionManagerCore = new ExecutionManagerCore(target, map); } public CodeBlockHandle? GetCodeBlockHandle(TargetCodePointer ip) => _executionManagerCore.GetCodeBlockHandle(ip); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_2.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_2.cs index a5f53d166f4119..6b84fda982ab5e 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_2.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExecutionManager/ExecutionManager_2.cs @@ -10,9 +10,11 @@ public sealed class ExecutionManager_2 : IExecutionManager { private IExecutionManager _executionManagerCore; - internal ExecutionManager_2(Target target, Data.RangeSectionMap topRangeSectionMap) + internal ExecutionManager_2(Target target) { - _executionManagerCore = new ExecutionManagerCore(target, topRangeSectionMap); + TargetPointer addr = target.ReadGlobalPointer(Constants.Globals.ExecutionManagerCodeRangeMapAddress); + Data.RangeSectionMap map = target.ProcessedData.GetOrAdd(addr); + _executionManagerCore = new ExecutionManagerCore(target, map); } public CodeBlockHandle? GetCodeBlockHandle(TargetCodePointer ip) => _executionManagerCore.GetCodeBlockHandle(ip); diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GC/GCFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GC/GCFactory.cs deleted file mode 100644 index 1f2230a3f59105..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GC/GCFactory.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class GCFactory : IContractFactory -{ - IGC IContractFactory.CreateContract(Target target, int version) - { - uint handlesPerBlock = target.ReadGlobal(Constants.Globals.HandlesPerBlock); - byte blockInvalid = target.ReadGlobal(Constants.Globals.BlockInvalid); - TargetPointer debugDestroyedHandleValue = target.ReadGlobalPointer(Constants.Globals.DebugDestroyedHandleValue); - uint handleMaxInternalTypes = target.ReadGlobal(Constants.Globals.HandleMaxInternalTypes); - uint handleSegmentSize = target.ReadGlobal(Constants.Globals.HandleSegmentSize); - return version switch - { - 1 => new GC_1(target, handlesPerBlock, blockInvalid, debugDestroyedHandleValue, handleMaxInternalTypes, handleSegmentSize), - _ => default(GC), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GC/GC_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GC/GC_1.cs index c6f64859ed5f28..9fd8ced2e9ed2d 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GC/GC_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GC/GC_1.cs @@ -44,14 +44,14 @@ private enum HandleType_1 private readonly uint _handleMaxInternalTypes; private readonly uint _handleSegmentSize; - internal GC_1(Target target, uint handlesPerBlock, byte blockInvalid, TargetPointer debugDestroyedHandleValue, uint handleMaxInternalTypes, uint handleSegmentSize) + internal GC_1(Target target) { _target = target; - _handlesPerBlock = handlesPerBlock; - _blockInvalid = blockInvalid; - _debugDestroyedHandleValue = debugDestroyedHandleValue; - _handleMaxInternalTypes = handleMaxInternalTypes; - _handleSegmentSize = handleSegmentSize; + _handlesPerBlock = target.ReadGlobal(Constants.Globals.HandlesPerBlock); + _blockInvalid = target.ReadGlobal(Constants.Globals.BlockInvalid); + _debugDestroyedHandleValue = target.ReadGlobalPointer(Constants.Globals.DebugDestroyedHandleValue); + _handleMaxInternalTypes = target.ReadGlobal(Constants.Globals.HandleMaxInternalTypes); + _handleSegmentSize = target.ReadGlobal(Constants.Globals.HandleSegmentSize); } string[] IGC.GetGCIdentifiers() diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/GCInfoFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/GCInfoFactory.cs deleted file mode 100644 index 50f1a36e7c70ee..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/GCInfo/GCInfoFactory.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using Microsoft.Diagnostics.DataContractReader.Contracts.GCInfoHelpers; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class GCInfoFactory : IContractFactory -{ - IGCInfo IContractFactory.CreateContract(Target target, int version) - { - RuntimeInfoArchitecture arch = target.Contracts.RuntimeInfo.GetTargetArchitecture(); - return (version, arch) switch - { - (1, RuntimeInfoArchitecture.X64) => new GCInfo_1(target), - (1, RuntimeInfoArchitecture.Arm64) => new GCInfo_1(target), - (1, RuntimeInfoArchitecture.Arm) => new GCInfo_1(target), - (1, RuntimeInfoArchitecture.LoongArch64) => new GCInfo_1(target), - (1, RuntimeInfoArchitecture.RiscV64) => new GCInfo_1(target), - _ => default(GCInfo), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/LoaderFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/LoaderFactory.cs deleted file mode 100644 index 6a1f8e96c39e9b..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/LoaderFactory.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class LoaderFactory : IContractFactory -{ - ILoader IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new Loader_1(target), - _ => default(Loader), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/NotificationsFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/NotificationsFactory.cs deleted file mode 100644 index f1cad1203f1b2e..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/NotificationsFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class NotificationsFactory : IContractFactory -{ - INotifications IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new Notifications_1(target), - _ => default(Notifications), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ObjectFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ObjectFactory.cs deleted file mode 100644 index dc1e97ccc84a98..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ObjectFactory.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class ObjectFactory : IContractFactory -{ - IObject IContractFactory.CreateContract(Target target, int version) - { - ulong methodTableOffset = (ulong)target.GetTypeInfo(DataType.Object).Fields["m_pMethTab"].Offset; - byte objectToMethodTableUnmask = target.ReadGlobal(Constants.Globals.ObjectToMethodTableUnmask); - TargetPointer stringMethodTable = target.ReadPointer( - target.ReadGlobalPointer(Constants.Globals.StringMethodTable)); - TargetPointer syncTableEntries = target.ReadPointer( - target.ReadGlobalPointer(Constants.Globals.SyncTableEntries)); - uint syncBlockIsHashOrSyncBlockIndex = target.ReadGlobal(Constants.Globals.SyncBlockIsHashOrSyncBlockIndex); - uint syncBlockIsHashCode = target.ReadGlobal(Constants.Globals.SyncBlockIsHashCode); - uint syncBlockHashCodeMask = target.ReadGlobal(Constants.Globals.SyncBlockHashCodeMask); - uint syncBlockIndexMask = target.ReadGlobal(Constants.Globals.SyncBlockIndexMask); - return version switch - { - 1 => new Object_1(target, methodTableOffset, objectToMethodTableUnmask, - stringMethodTable, syncTableEntries, - syncBlockIsHashOrSyncBlockIndex, syncBlockIsHashCode, - syncBlockHashCodeMask, syncBlockIndexMask), - _ => default(Object), - }; - } - -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs index dbdbd7e3ccaacb..ca3ca25c801122 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs @@ -19,20 +19,17 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts; private readonly uint _syncBlockHashCodeMask; private readonly uint _syncBlockIndexMask; - internal Object_1(Target target, ulong methodTableOffset, byte objectToMethodTableUnmask, - TargetPointer stringMethodTable, TargetPointer syncTableEntries, - uint syncBlockIsHashOrSyncBlockIndex, uint syncBlockIsHashCode, - uint syncBlockHashCodeMask, uint syncBlockIndexMask) + internal Object_1(Target target) { _target = target; - _methodTableOffset = methodTableOffset; - _stringMethodTable = stringMethodTable; - _objectToMethodTableUnmask = objectToMethodTableUnmask; - _syncTableEntries = syncTableEntries; - _syncBlockIsHashOrSyncBlockIndex = syncBlockIsHashOrSyncBlockIndex; - _syncBlockIsHashCode = syncBlockIsHashCode; - _syncBlockHashCodeMask = syncBlockHashCodeMask; - _syncBlockIndexMask = syncBlockIndexMask; + _methodTableOffset = (ulong)target.GetTypeInfo(DataType.Object).Fields["m_pMethTab"].Offset; + _objectToMethodTableUnmask = target.ReadGlobal(Constants.Globals.ObjectToMethodTableUnmask); + _stringMethodTable = target.ReadPointer(target.ReadGlobalPointer(Constants.Globals.StringMethodTable)); + _syncTableEntries = target.ReadPointer(target.ReadGlobalPointer(Constants.Globals.SyncTableEntries)); + _syncBlockIsHashOrSyncBlockIndex = target.ReadGlobal(Constants.Globals.SyncBlockIsHashOrSyncBlockIndex); + _syncBlockIsHashCode = target.ReadGlobal(Constants.Globals.SyncBlockIsHashCode); + _syncBlockHashCodeMask = target.ReadGlobal(Constants.Globals.SyncBlockHashCodeMask); + _syncBlockIndexMask = target.ReadGlobal(Constants.Globals.SyncBlockIndexMask); } public TargetPointer GetMethodTableAddress(TargetPointer address) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadataFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadataFactory.cs deleted file mode 100644 index 438b0a93788f53..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadataFactory.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class PlatformMetadataFactory : IContractFactory -{ - IPlatformMetadata IContractFactory.CreateContract(Target target, int version) - { - TargetPointer cdacMetadataAddress = target.ReadGlobalPointer(Constants.Globals.PlatformMetadata); - Data.PlatformMetadata cdacMetadata = target.ProcessedData.GetOrAdd(cdacMetadataAddress); - return version switch - { - 1 => new PlatformMetadata_1(target, cdacMetadata), - _ => default(PlatformMetadata), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadata_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadata_1.cs index 0e317fa202347e..5cb85410897c06 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadata_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PlatformMetadata_1.cs @@ -10,10 +10,11 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts; internal readonly Target _target; private readonly Data.PlatformMetadata _cdacMetadata; - public PlatformMetadata_1(Target target, Data.PlatformMetadata cdacMetadata) + public PlatformMetadata_1(Target target) { _target = target; - _cdacMetadata = cdacMetadata; + TargetPointer cdacMetadataAddress = target.ReadGlobalPointer(Constants.Globals.PlatformMetadata); + _cdacMetadata = target.ProcessedData.GetOrAdd(cdacMetadataAddress); } TargetPointer IPlatformMetadata.GetPrecodeMachineDescriptor() diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubsFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubsFactory.cs deleted file mode 100644 index c47d671ed5058d..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubsFactory.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class PrecodeStubsFactory : IContractFactory -{ - IPrecodeStubs IContractFactory.CreateContract(Target target, int version) - { - IPlatformMetadata cDacMetadata = target.Contracts.PlatformMetadata; - TargetPointer precodeMachineDescriptorAddress = cDacMetadata.GetPrecodeMachineDescriptor(); - Data.PrecodeMachineDescriptor precodeMachineDescriptor = target.ProcessedData.GetOrAdd(precodeMachineDescriptorAddress); - CodePointerFlags codePointerFlags= cDacMetadata.GetCodePointerFlags(); - return version switch - { - 1 => new PrecodeStubs_1(target, precodeMachineDescriptor, codePointerFlags), - 2 => new PrecodeStubs_2(target, precodeMachineDescriptor, codePointerFlags), - 3 => new PrecodeStubs_3(target, precodeMachineDescriptor, codePointerFlags), - _ => default(PrecodeStubs), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_1.cs index d34699a6314f7e..35dac689d5ed99 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_1.cs @@ -107,5 +107,5 @@ static TStubPrecodeData GetStubPrecodeData(TargetPointer stubInstrPointer, Targe internal sealed class PrecodeStubs_1 : PrecodeStubsCommon { - public PrecodeStubs_1(Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor, CodePointerFlags codePointerFlags) : base(target, precodeMachineDescriptor, codePointerFlags) { } + public PrecodeStubs_1(Target target) : base(target) { } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_2.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_2.cs index f62cb97b29c255..aa888f923c5a76 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_2.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_2.cs @@ -43,5 +43,5 @@ public static byte StubPrecodeData_GetType(Data.StubPrecodeData_2 stubPrecodeDat internal sealed class PrecodeStubs_2 : PrecodeStubsCommon { - public PrecodeStubs_2(Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor, CodePointerFlags codePointerFlags) : base(target, precodeMachineDescriptor, codePointerFlags) { } + public PrecodeStubs_2(Target target) : base(target) { } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_3.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_3.cs index d9c52c907defee..2507df5a116205 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_3.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_3.cs @@ -100,5 +100,5 @@ static bool ReadBytesAndCompare(TargetPointer instrAddress, byte[] expectedByteP internal sealed class PrecodeStubs_3 : PrecodeStubsCommon { - public PrecodeStubs_3(Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor, CodePointerFlags codePointerFlags) : base(target, precodeMachineDescriptor, codePointerFlags) { } + public PrecodeStubs_3(Target target) : base(target) { } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_Common.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_Common.cs index 88c61ef14cb742..c8b76481107e5c 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_Common.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/PrecodeStubs_Common.cs @@ -131,11 +131,13 @@ internal ValidPrecode GetPrecodeFromEntryPoint(TargetCodePointer entryPoint) } throw new InvalidOperationException($"Invalid precode type 0x{instrPointer:x16}"); } - public PrecodeStubsCommon(Target target, Data.PrecodeMachineDescriptor precodeMachineDescriptor, CodePointerFlags codePointerFlags) + public PrecodeStubsCommon(Target target) { _target = target; - MachineDescriptor = precodeMachineDescriptor; - _codePointerFlags = codePointerFlags; + IPlatformMetadata pm = target.Contracts.PlatformMetadata; + TargetPointer descAddr = pm.GetPrecodeMachineDescriptor(); + MachineDescriptor = target.ProcessedData.GetOrAdd(descAddr); + _codePointerFlags = pm.GetCodePointerFlags(); } TargetPointer IPrecodeStubs.GetMethodDescFromStubAddress(TargetCodePointer entryPoint) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJITFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJITFactory.cs deleted file mode 100644 index 27572ba805eb37..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJITFactory.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class ReJITFactory : IContractFactory -{ - IReJIT IContractFactory.CreateContract(Target target, int version) - { - TargetPointer profControlBlockAddress = target.ReadGlobalPointer(Constants.Globals.ProfilerControlBlock); - Data.ProfControlBlock profControlBlock = target.ProcessedData.GetOrAdd(profControlBlockAddress); - return version switch - { - 1 => new ReJIT_1(target, profControlBlock), - _ => default(ReJIT), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs index eb9d7af509a342..3e4e79d89a245e 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs @@ -30,10 +30,11 @@ public enum RejitFlags : uint kStateMask = 0x0000000F } - public ReJIT_1(Target target, Data.ProfControlBlock profControlBlock) + public ReJIT_1(Target target) { _target = target; - _profControlBlock = profControlBlock; + TargetPointer profControlBlockAddress = target.ReadGlobalPointer(Constants.Globals.ProfilerControlBlock); + _profControlBlock = target.ProcessedData.GetOrAdd(profControlBlockAddress); } bool IReJIT.IsEnabled() diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeInfoFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeInfoFactory.cs deleted file mode 100644 index de468ffc96dc75..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeInfoFactory.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class RuntimeInfoFactory : IContractFactory -{ - IRuntimeInfo IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new RuntimeInfo_1(target), - _ => default(RuntimeInfo), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystemFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystemFactory.cs deleted file mode 100644 index 9c62c256421fd8..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystemFactory.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class RuntimeTypeSystemFactory : IContractFactory -{ - IRuntimeTypeSystem IContractFactory.CreateContract(Target target, int version) - { - TargetPointer targetPointer = target.ReadGlobalPointer(Constants.Globals.FreeObjectMethodTable); - TargetPointer freeObjectMethodTable = target.ReadPointer(targetPointer); - TargetPointer continuationMethodTablePointer = target.ReadGlobalPointer(Constants.Globals.ContinuationMethodTable); - TargetPointer continuationMethodTable = target.ReadPointer(continuationMethodTablePointer); - ulong methodDescAlignment = target.ReadGlobal(Constants.Globals.MethodDescAlignment); - return version switch - { - 1 => new RuntimeTypeSystem_1(target, new RuntimeTypeSystemHelpers.TypeValidation(target, continuationMethodTable), new RuntimeTypeSystemHelpers.MethodValidation(target, methodDescAlignment), freeObjectMethodTable, continuationMethodTable, methodDescAlignment), - _ => default(RuntimeTypeSystem), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs index 92d50cd31f8d5e..d2c16b5b098f39 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs @@ -417,14 +417,16 @@ private StoredSigMethodDesc(Target target, TargetPointer methodDescPointer) } } - internal RuntimeTypeSystem_1(Target target, TypeValidation typeValidation, MethodValidation methodValidation, TargetPointer freeObjectMethodTablePointer, TargetPointer continuationMethodTablePointer, ulong methodDescAlignment) + internal RuntimeTypeSystem_1(Target target) { _target = target; - _freeObjectMethodTablePointer = freeObjectMethodTablePointer; - _continuationMethodTablePointer = continuationMethodTablePointer; - _methodDescAlignment = methodDescAlignment; - _typeValidation = typeValidation; - _methodValidation = methodValidation; + _freeObjectMethodTablePointer = target.ReadPointer( + target.ReadGlobalPointer(Constants.Globals.FreeObjectMethodTable)); + _continuationMethodTablePointer = target.ReadPointer( + target.ReadGlobalPointer(Constants.Globals.ContinuationMethodTable)); + _methodDescAlignment = target.ReadGlobal(Constants.Globals.MethodDescAlignment); + _typeValidation = new TypeValidation(target, _continuationMethodTablePointer); + _methodValidation = new MethodValidation(target, _methodDescAlignment); _methodValidation.SetMethodTableQueries(new NonValidatedMethodTableQueries(this)); } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/SHashFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/SHashFactory.cs deleted file mode 100644 index db45e8c3fcc118..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/SHashFactory.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class SHashFactory : IContractFactory -{ - ISHash IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new SHash_1(target), - _ => default(SHash), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Signature/SignatureDecoderFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Signature/SignatureDecoderFactory.cs deleted file mode 100644 index 9715fc7de8adb9..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Signature/SignatureDecoderFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class SignatureDecoderFactory : IContractFactory -{ - ISignatureDecoder IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new SignatureDecoder_1(target), - _ => default(SignatureDecoder), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalkFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalkFactory.cs deleted file mode 100644 index 3a05fdb48ddc15..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/StackWalkFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class StackWalkFactory : IContractFactory -{ - IStackWalk IContractFactory.CreateContract(Target target, int version) - { - return version switch - { - 1 => new StackWalk_1(target), - _ => default(StackWalk), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs index 7940f14b7faa7f..b3eb52892a0e17 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StressLog.cs @@ -10,25 +10,12 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts; -public sealed class StressLogFactory : IContractFactory -{ - public IStressLog CreateContract(Target target, int version) - { - return version switch - { - 1 => new StressLog_1(target), - 2 => new StressLog_2(target), - _ => default(StressLog), - }; - } -} - -file interface IStressMessageReader +internal interface IStressMessageReader { StressMsgData GetStressMsgData(Data.StressMsg msg, Func getFormatPointerFromOffset); } -file sealed class StressLogTraversal(Target target, IStressMessageReader messageReader) +internal sealed class StressLogTraversal(Target target, IStressMessageReader messageReader) { private bool StressLogChunkValid(Data.StressLogChunk chunk) { @@ -277,7 +264,7 @@ public static StressLogMemory Create(Target target, TargetPointer address) } } -file sealed class SmallStressMessageReader(Target target) : IStressMessageReader +internal sealed class SmallStressMessageReader(Target target) : IStressMessageReader { public StressMsgData GetStressMsgData(Data.StressMsg msg, Func getFormatPointerFromOffset) { @@ -307,7 +294,7 @@ public StressMsgData GetStressMsgData(Data.StressMsg msg, Func getFormatPointerFromOffset) { @@ -344,7 +331,7 @@ public StressMsgData GetStressMsgData(Data.StressMsg msg, Func -{ - ISyncBlock IContractFactory.CreateContract(Target target, int version) - { - TargetPointer syncTableEntries = target.ReadPointer( - target.ReadGlobalPointer(Constants.Globals.SyncTableEntries)); - ulong syncBlockLinkOffset = (ulong)target.GetTypeInfo(DataType.SyncBlock).Fields[nameof(Data.SyncBlock.LinkNext)].Offset; - return version switch - { - 1 => new SyncBlock_1(target, syncTableEntries, syncBlockLinkOffset), - _ => default(SyncBlock), - }; - } - -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/SyncBlock_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/SyncBlock_1.cs index 0a51b7cc532cdf..d1eb3f83b9b478 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/SyncBlock_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/SyncBlock_1.cs @@ -17,11 +17,11 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts; private readonly TargetPointer _syncTableEntries; private readonly ulong _syncBlockLinkOffset; - internal SyncBlock_1(Target target, TargetPointer syncTableEntries, ulong syncBlockLinkOffset) + internal SyncBlock_1(Target target) { _target = target; - _syncTableEntries = syncTableEntries; - _syncBlockLinkOffset = syncBlockLinkOffset; + _syncTableEntries = target.ReadPointer(target.ReadGlobalPointer(Constants.Globals.SyncTableEntries)); + _syncBlockLinkOffset = (ulong)target.GetTypeInfo(DataType.SyncBlock).Fields[nameof(Data.SyncBlock.LinkNext)].Offset; } public TargetPointer GetSyncBlock(uint index) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ThreadFactory.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ThreadFactory.cs deleted file mode 100644 index e3f98013ad3ee9..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ThreadFactory.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; - -public sealed class ThreadFactory : IContractFactory -{ - IThread IContractFactory.CreateContract(Target target, int version) - { - TargetPointer threadStorePointer = target.ReadGlobalPointer(Constants.Globals.ThreadStore); - TargetPointer threadStore = target.ReadPointer(threadStorePointer); - return version switch - { - 1 => new Thread_1(target, threadStore), - _ => default(Thread), - }; - } -} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs index 5f346dabad4701..ab1aa563cbe02a 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread_1.cs @@ -19,10 +19,10 @@ private enum TLSIndexType DirectOnThreadLocalData = 2, // IndexOffset for this form of TLS index is an offset into the ThreadLocalData structure itself. This is used for very high performance scenarios, and scenario where the runtime native code needs to hold a TLS pointer to a managed TLS slot. Each one of these is hand-opted into this model. }; - internal Thread_1(Target target, TargetPointer threadStore) + internal Thread_1(Target target) { _target = target; - _threadStoreAddr = threadStore; + _threadStoreAddr = target.ReadPointer(target.ReadGlobalPointer(Constants.Globals.ThreadStore)); // Get the offset into Thread of the SLink. We use this to find the actual // first thread from the linked list node contained by the first thread. diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/CoreCLRContracts.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/CoreCLRContracts.cs new file mode 100644 index 00000000000000..d89b6233c5ccc6 --- /dev/null +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/CoreCLRContracts.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Diagnostics.DataContractReader.Contracts.GCInfoHelpers; + +namespace Microsoft.Diagnostics.DataContractReader.Contracts; + +/// +/// Registers all CoreCLR contract implementations. +/// External packages (NativeAOT, Mono, etc.) follow the same pattern +/// with their own static Register method. +/// +public static class CoreCLRContracts +{ + public static void Register(ContractRegistry registry) + { + registry.Register(1, static t => new Exception_1(t)); + registry.Register(1, static t => new Loader_1(t)); + registry.Register(1, static t => new EcmaMetadata_1(t)); + registry.Register(1, static t => new DacStreams_1(t)); + registry.Register(1, static t => new CodeVersions_1(t)); + registry.Register(1, static t => new StackWalk_1(t)); + registry.Register(1, static t => new RuntimeInfo_1(t)); + registry.Register(1, static t => new ComWrappers_1(t)); + registry.Register(1, static t => new SHash_1(t)); + registry.Register(1, static t => new Notifications_1(t)); + registry.Register(1, static t => new SignatureDecoder_1(t)); + registry.Register(1, static t => new BuiltInCOM_1(t)); + registry.Register(1, static t => new ConditionalWeakTable_1(t)); + registry.Register(1, static t => new AuxiliarySymbols_1(t)); + registry.Register(1, static t => new Debugger_1(t)); + + registry.Register(1, static t => new DebugInfo_1(t)); + registry.Register(2, static t => new DebugInfo_2(t)); + registry.Register(1, static t => new StressLog_1(t)); + registry.Register(2, static t => new StressLog_2(t)); + + registry.Register(1, static t => new Thread_1(t)); + + registry.Register(1, static t => new RuntimeTypeSystem_1(t)); + + registry.Register(1, static t => new Object_1(t)); + + registry.Register(1, static t => new PlatformMetadata_1(t)); + + registry.Register(1, static t => new PrecodeStubs_1(t)); + registry.Register(2, static t => new PrecodeStubs_2(t)); + registry.Register(3, static t => new PrecodeStubs_3(t)); + + registry.Register(1, static t => new ReJIT_1(t)); + + registry.Register(1, static t => new GC_1(t)); + + registry.Register(1, static t => + { + RuntimeInfoArchitecture arch = t.Contracts.RuntimeInfo.GetTargetArchitecture(); + return arch switch + { + RuntimeInfoArchitecture.X64 => new GCInfo_1(t), + RuntimeInfoArchitecture.Arm64 => new GCInfo_1(t), + RuntimeInfoArchitecture.Arm => new GCInfo_1(t), + RuntimeInfoArchitecture.LoongArch64 => new GCInfo_1(t), + RuntimeInfoArchitecture.RiscV64 => new GCInfo_1(t), + _ => default(GCInfo), + }; + }); + + registry.Register(1, static t => new SyncBlock_1(t)); + + registry.Register(1, static t => new ExecutionManager_1(t)); + registry.Register(2, static t => new ExecutionManager_2(t)); + } +} diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs index c8bc640f12d84d..10c9497447efb5 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs @@ -8,75 +8,50 @@ namespace Microsoft.Diagnostics.DataContractReader; /// -/// Contract registry that caches contracts for a target +/// Contract registry that resolves contracts by (type, version) lookup. +/// Has no knowledge of any specific contracts — all implementations are +/// registered from outside via . /// internal sealed class CachingContractRegistry : ContractRegistry { public delegate bool TryGetContractVersionDelegate(string contractName, out int version); - // Contracts that have already been created for a target. - // Items should not be removed from this, only added. + private readonly Dictionary _contracts = []; - private readonly Dictionary> _factories; + private readonly Dictionary<(Type, int), Func> _creators = []; private readonly Target _target; private readonly TryGetContractVersionDelegate _tryGetContractVersion; - public CachingContractRegistry(Target target, TryGetContractVersionDelegate tryGetContractVersion, IEnumerable> additionalFactories, Action>>? configureFactories = null) + public CachingContractRegistry(Target target, TryGetContractVersionDelegate tryGetContractVersion, params Action[] contractRegistrations) { _target = target; _tryGetContractVersion = tryGetContractVersion; - _factories = new() - { - [typeof(IException)] = new ExceptionFactory(), - [typeof(ILoader)] = new LoaderFactory(), - [typeof(IEcmaMetadata)] = new EcmaMetadataFactory(), - [typeof(IObject)] = new ObjectFactory(), - [typeof(IThread)] = new ThreadFactory(), - [typeof(IRuntimeTypeSystem)] = new RuntimeTypeSystemFactory(), - [typeof(IDacStreams)] = new DacStreamsFactory(), - [typeof(IExecutionManager)] = new ExecutionManagerFactory(), - [typeof(ICodeVersions)] = new CodeVersionsFactory(), - [typeof(IPlatformMetadata)] = new PlatformMetadataFactory(), - [typeof(IPrecodeStubs)] = new PrecodeStubsFactory(), - [typeof(IReJIT)] = new ReJITFactory(), - [typeof(IStackWalk)] = new StackWalkFactory(), - [typeof(IRuntimeInfo)] = new RuntimeInfoFactory(), - [typeof(IComWrappers)] = new ComWrappersFactory(), - [typeof(IDebugInfo)] = new DebugInfoFactory(), - [typeof(ISHash)] = new SHashFactory(), - [typeof(IGC)] = new GCFactory(), - [typeof(IGCInfo)] = new GCInfoFactory(), - [typeof(INotifications)] = new NotificationsFactory(), - [typeof(ISignatureDecoder)] = new SignatureDecoderFactory(), - [typeof(ISyncBlock)] = new SyncBlockFactory(), - [typeof(IBuiltInCOM)] = new BuiltInCOMFactory(), - [typeof(IConditionalWeakTable)] = new ConditionalWeakTableFactory(), - [typeof(IAuxiliarySymbols)] = new AuxiliarySymbolsFactory(), - [typeof(IDebugger)] = new DebuggerFactory(), - }; - foreach (IContractFactory factory in additionalFactories) + foreach (Action register in contractRegistrations) { - _factories[factory.ContractType] = factory; + register(this); } - configureFactories?.Invoke(_factories); + } + + public override void Register(int version, Func creator) + { + _creators[(typeof(TContract), version)] = t => creator(t); } public override TContract GetContract() { - if (_contracts.TryGetValue(typeof(TContract), out IContract? contractMaybe)) - return (TContract)contractMaybe; + if (_contracts.TryGetValue(typeof(TContract), out IContract? cached)) + return (TContract)cached; if (!_tryGetContractVersion(TContract.Name, out int version)) - throw new NotImplementedException(); + throw new NotImplementedException($"Contract '{TContract.Name}' is not present in the contract descriptor."); + + if (!_creators.TryGetValue((typeof(TContract), version), out Func? creator)) + throw new NotImplementedException($"No implementation registered for contract '{TContract.Name}' version {version}."); - if (!_factories.TryGetValue(typeof(TContract), out IContractFactory? factory)) - throw new NotImplementedException(); - // Create and register the contract - TContract contract = (TContract)factory.CreateContract(_target, version); + TContract contract = (TContract)creator(_target); if (_contracts.TryAdd(typeof(TContract), contract)) return contract; - // Contract was already registered by someone else return (TContract)_contracts[typeof(TContract)]; } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs index 71786f8d9a7d30..3fb760eca59586 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs @@ -54,7 +54,9 @@ private readonly struct Configuration /// /// The offset of the contract descriptor in the target memory /// A callback to read memory blocks at a given address from the target + /// A callback to write memory blocks at a given address to the target /// A callback to fetch a thread's context + /// Registration actions that populate the contract registry (e.g., ) /// The target object. /// If a target instance could be created, true; otherwise, false. public static bool TryCreate( @@ -62,7 +64,7 @@ public static bool TryCreate( ReadFromTargetDelegate readFromTarget, WriteToTargetDelegate writeToTarget, GetTargetThreadContextDelegate getThreadContext, - IEnumerable> additionalFactories, + Action[] contractRegistrations, [NotNullWhen(true)] out ContractDescriptorTarget? target) { DataTargetDelegates dataTargetDelegates = new DataTargetDelegates(readFromTarget, writeToTarget, getThreadContext); @@ -71,7 +73,7 @@ public static bool TryCreate( dataTargetDelegates, out Descriptor[] descriptors)) { - target = new ContractDescriptorTarget(descriptors, dataTargetDelegates, additionalFactories); + target = new ContractDescriptorTarget(descriptors, dataTargetDelegates, contractRegistrations); return true; } @@ -85,9 +87,11 @@ public static bool TryCreate( /// The contract descriptor to use for this target /// The values for any global pointers specified in the contract descriptor. /// A callback to read memory blocks at a given address from the target + /// A callback to write memory blocks at a given address to the target /// A callback to fetch a thread's context /// Whether the target is little-endian /// The size of a pointer in bytes in the target process. + /// Registration actions that populate the contract registry (e.g., ) /// The target object. public static ContractDescriptorTarget Create( ContractDescriptorParser.ContractDescriptor contractDescriptor, @@ -97,7 +101,7 @@ public static ContractDescriptorTarget Create( GetTargetThreadContextDelegate getThreadContext, bool isLittleEndian, int pointerSize, - IEnumerable> additionalFactories) + Action[]? contractRegistrations = null) { return new ContractDescriptorTarget( [ @@ -109,12 +113,12 @@ public static ContractDescriptorTarget Create( } ], new DataTargetDelegates(readFromTarget, writeToTarget, getThreadContext), - additionalFactories); + contractRegistrations ?? []); } - private ContractDescriptorTarget(Descriptor[] descriptors, DataTargetDelegates dataTargetDelegates, IEnumerable> additionalFactories) + private ContractDescriptorTarget(Descriptor[] descriptors, DataTargetDelegates dataTargetDelegates, Action[] contractRegistrations) { - Contracts = new CachingContractRegistry(this, this.TryGetContractVersion, additionalFactories); + Contracts = new CachingContractRegistry(this, this.TryGetContractVersion, contractRegistrations); ProcessedData = new DataCache(this); _config = descriptors[0].Config; _dataTargetDelegates = dataTargetDelegates; diff --git a/src/native/managed/cdac/mscordaccore_universal/Entrypoints.cs b/src/native/managed/cdac/mscordaccore_universal/Entrypoints.cs index 9cd2f981951850..af14a0a1dbba09 100644 --- a/src/native/managed/cdac/mscordaccore_universal/Entrypoints.cs +++ b/src/native/managed/cdac/mscordaccore_universal/Entrypoints.cs @@ -45,7 +45,7 @@ private static unsafe int Init( return readThreadContext(threadId, contextFlags, (uint)buffer.Length, bufferPtr, delegateContext); } }, - [], + [Contracts.CoreCLRContracts.Register], out ContractDescriptorTarget? target)) return -1; @@ -189,7 +189,7 @@ private static unsafe int CLRDataCreateInstanceImpl(Guid* pIID, IntPtr /*ICLRDat return dataTarget.GetThreadContext(threadId, contextFlags, (uint)bufferToFill.Length, bufferPtr); } }, - [], + [Contracts.CoreCLRContracts.Register], out ContractDescriptorTarget? target)) { return -1; diff --git a/src/native/managed/cdac/tests/AuxiliarySymbolsTests.cs b/src/native/managed/cdac/tests/AuxiliarySymbolsTests.cs index 2ee47edc1ea3a3..79f7e8d65fa546 100644 --- a/src/native/managed/cdac/tests/AuxiliarySymbolsTests.cs +++ b/src/native/managed/cdac/tests/AuxiliarySymbolsTests.cs @@ -91,8 +91,8 @@ private static Target CreateTarget( .AddGlobals( (Constants.Globals.AuxiliarySymbols, arrayAddress), (Constants.Globals.AuxiliarySymbolCount, countFragment.Address)) - .AddContract(_ => Mock.Of(p => p.GetCodePointerFlags() == default(CodePointerFlags))) - .AddContract(static target => ((IContractFactory)new AuxiliarySymbolsFactory()).CreateContract(target, 1)) + .AddMockContract(Mock.Of(p => p.GetCodePointerFlags() == default(CodePointerFlags))) + .AddContract(version: 1) .Build(); } diff --git a/src/native/managed/cdac/tests/BuiltInCOMTests.cs b/src/native/managed/cdac/tests/BuiltInCOMTests.cs index 48ca8d36ce29fa..eaa5cd0afa3844 100644 --- a/src/native/managed/cdac/tests/BuiltInCOMTests.cs +++ b/src/native/managed/cdac/tests/BuiltInCOMTests.cs @@ -21,21 +21,18 @@ private static IBuiltInCOM CreateBuiltInCOM( ISyncBlock? syncBlock = null, int minAlign = 16) { - TargetTestHelpers targetTestHelpers = new(arch); - MockMemorySpace.Builder builder = new(targetTestHelpers); - MockMemorySpace.BumpAllocator allocator = builder.CreateAllocator(AllocationRangeStart, AllocationRangeEnd, minAlign: minAlign); - MockBuiltInComBuilder builtInCom = new(builder, allocator, arch); + var targetBuilder = new TestPlaceholderTarget.Builder(arch); + MockMemorySpace.BumpAllocator allocator = targetBuilder.MemoryBuilder.CreateAllocator(AllocationRangeStart, AllocationRangeEnd, minAlign: minAlign); + MockBuiltInComBuilder builtInCom = new(targetBuilder.MemoryBuilder, allocator, arch); configure(builtInCom); - var target = new TestPlaceholderTarget( - arch, - builder.GetMemoryContext().ReadFromTarget, - CreateContractTypes(builtInCom), - CreateContractGlobals(builtInCom)); ISyncBlock syncBlockContract = syncBlock ?? Mock.Of(); - target.SetContracts(Mock.Of( - c => c.BuiltInCOM == ((IContractFactory)new BuiltInCOMFactory()).CreateContract(target, 1) - && c.SyncBlock == syncBlockContract)); + var target = targetBuilder + .AddTypes(CreateContractTypes(builtInCom)) + .AddGlobals(CreateContractGlobals(builtInCom)) + .AddContract(version: 1) + .AddMockContract(syncBlockContract) + .Build(); return target.Contracts.BuiltInCOM; } diff --git a/src/native/managed/cdac/tests/ClrDataExceptionStateTests.cs b/src/native/managed/cdac/tests/ClrDataExceptionStateTests.cs index 0319362d07f0c2..2bb87b3288c8e2 100644 --- a/src/native/managed/cdac/tests/ClrDataExceptionStateTests.cs +++ b/src/native/managed/cdac/tests/ClrDataExceptionStateTests.cs @@ -18,17 +18,15 @@ private static (TestPlaceholderTarget Target, TargetPointer ThrownObjectHandle) { TargetPointer exceptionObjectAddr = new TargetPointer(0x5000); TargetTestHelpers helpers = new(arch); - MockMemorySpace.Builder builder = new(helpers); - var allocator = builder.CreateAllocator(0x1_0000, 0x2_0000); + var targetBuilder = new TestPlaceholderTarget.Builder(arch); + var allocator = targetBuilder.MemoryBuilder.CreateAllocator(0x1_0000, 0x2_0000); MockMemorySpace.HeapFragment handleFragment = allocator.Allocate((ulong)helpers.PointerSize, "ThrownObjectHandle"); helpers.WritePointer(handleFragment.Data, exceptionObjectAddr); - builder.AddHeapFragment(handleFragment); + targetBuilder.MemoryBuilder.AddHeapFragment(handleFragment); TargetPointer thrownObjectHandle = new TargetPointer(handleFragment.Address); - var target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget); - var mockException = new Mock(); mockException.Setup(e => e.GetExceptionData(exceptionObjectAddr)).Returns(new ExceptionData( Message: messageAddr, @@ -44,9 +42,10 @@ private static (TestPlaceholderTarget Target, TargetPointer ThrownObjectHandle) if (messageAddr != TargetPointer.Null && messageString is not null) mockObject.Setup(o => o.GetStringValue(messageAddr)).Returns(messageString); - target.SetContracts(Mock.Of( - c => c.Exception == mockException.Object - && c.Object == mockObject.Object)); + var target = targetBuilder + .AddMockContract(mockException) + .AddMockContract(mockObject) + .Build(); return (target, thrownObjectHandle); } @@ -90,8 +89,10 @@ private static (TestPlaceholderTarget Target, IXCLRDataTask Task) CreateTargetWi LastThrownObjectHandle: lastThrownObjectHandle, NextThread: TargetPointer.Null)); - var target = new TestPlaceholderTarget(arch, (ulong _, Span _) => -1); - target.SetContracts(Mock.Of(c => c.Thread == mockThread.Object)); + var target = new TestPlaceholderTarget.Builder(arch) + .UseReader((ulong _, Span _) => -1) + .AddMockContract(mockThread) + .Build(); IXCLRDataTask task = new ClrDataTask(threadAddr, target, null); return (target, task); @@ -365,8 +366,10 @@ public void GetPrevious_HasPrevious_ReturnsState(MockTarget.Architecture arch) var mockException = new Mock(); SetupGetNestedExceptionInfo(mockException, previousExInfoAddr, nextNestedException, prevThrownObjectHandle); - var target = new TestPlaceholderTarget(arch, (ulong _, Span _) => -1); - target.SetContracts(Mock.Of(c => c.Exception == mockException.Object)); + var target = new TestPlaceholderTarget.Builder(arch) + .UseReader((ulong _, Span _) => -1) + .AddMockContract(mockException) + .Build(); IXCLRDataExceptionState exceptionState = new ClrDataExceptionState( target, @@ -398,8 +401,10 @@ public void GetPrevious_NestedExceptionsChain(MockTarget.Architecture arch) SetupGetNestedExceptionInfo(mockException, firstNestedAddr, secondNestedAddr, firstHandle); SetupGetNestedExceptionInfo(mockException, secondNestedAddr, TargetPointer.Null, secondHandle); - var target = new TestPlaceholderTarget(arch, (ulong _, Span _) => -1); - target.SetContracts(Mock.Of(c => c.Exception == mockException.Object)); + var target = new TestPlaceholderTarget.Builder(arch) + .UseReader((ulong _, Span _) => -1) + .AddMockContract(mockException) + .Build(); IXCLRDataExceptionState exceptionState = new ClrDataExceptionState( target, @@ -440,15 +445,14 @@ private static (IXCLRDataTask Task, string ExpectedMessage) CreateTargetWithLast TargetPointer threadAddr = new TargetPointer(0x1000); TargetTestHelpers helpers = new(arch); - MockMemorySpace.Builder builder = new(helpers); - var allocator = builder.CreateAllocator(0x1_0000, 0x2_0000); + var targetBuilder = new TestPlaceholderTarget.Builder(arch); + var allocator = targetBuilder.MemoryBuilder.CreateAllocator(0x1_0000, 0x2_0000); MockMemorySpace.HeapFragment handleFragment = allocator.Allocate((ulong)helpers.PointerSize, "LastThrownObjectHandle"); helpers.WritePointer(handleFragment.Data, exceptionObjectAddr); - builder.AddHeapFragment(handleFragment); + targetBuilder.MemoryBuilder.AddHeapFragment(handleFragment); TargetPointer lastThrownObjectHandle = new TargetPointer(handleFragment.Address); - var target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget); var mockThread = new Mock(); mockThread.Setup(t => t.GetThreadData(threadAddr)).Returns(new ThreadData( ThreadAddress: threadAddr, @@ -477,10 +481,11 @@ private static (IXCLRDataTask Task, string ExpectedMessage) CreateTargetWithLast var mockObject = new Mock(); mockObject.Setup(o => o.GetStringValue(messageAddr)).Returns(expectedMessage); - target.SetContracts(Mock.Of( - c => c.Thread == mockThread.Object - && c.Exception == mockException.Object - && c.Object == mockObject.Object)); + var target = targetBuilder + .AddMockContract(mockThread) + .AddMockContract(mockException) + .AddMockContract(mockObject) + .Build(); IXCLRDataTask task = new ClrDataTask(threadAddr, target, null); return (task, expectedMessage); diff --git a/src/native/managed/cdac/tests/ClrDataTaskTests.cs b/src/native/managed/cdac/tests/ClrDataTaskTests.cs index 36d87438814fc2..eb8e301172bd79 100644 --- a/src/native/managed/cdac/tests/ClrDataTaskTests.cs +++ b/src/native/managed/cdac/tests/ClrDataTaskTests.cs @@ -14,24 +14,23 @@ public unsafe class ClrDataTaskTests public void GetCurrentAppDomain(MockTarget.Architecture arch) { TargetTestHelpers helpers = new(arch); - MockMemorySpace.Builder builder = new(helpers); ulong globalPtrAddr = 0x1000; ulong expectedAppDomain = 0x2000; + var targetBuilder = new TestPlaceholderTarget.Builder(arch); byte[] ptrData = new byte[helpers.PointerSize]; helpers.WritePointer(ptrData, expectedAppDomain); - builder.AddHeapFragment(new MockMemorySpace.HeapFragment + targetBuilder.MemoryBuilder.AddHeapFragment(new MockMemorySpace.HeapFragment { Address = globalPtrAddr, Data = ptrData, Name = "AppDomainGlobalPointer" }); - var target = new TestPlaceholderTarget( - arch, - builder.GetMemoryContext().ReadFromTarget, - globals: [(Constants.Globals.AppDomain, globalPtrAddr)]); + var target = targetBuilder + .AddGlobals((Constants.Globals.AppDomain, globalPtrAddr)) + .Build(); TargetPointer taskAddress = new TargetPointer(0x5000); IXCLRDataTask task = new ClrDataTask(taskAddress, target, legacyImpl: null); diff --git a/src/native/managed/cdac/tests/CodeVersionsTests.cs b/src/native/managed/cdac/tests/CodeVersionsTests.cs index dc36299536f538..e987dec22e6bb9 100644 --- a/src/native/managed/cdac/tests/CodeVersionsTests.cs +++ b/src/native/managed/cdac/tests/CodeVersionsTests.cs @@ -153,19 +153,14 @@ internal Target CreateTarget( mockExecutionManager ??= new Mock(); mockRuntimeTypeSystem ??= new Mock(); - TestPlaceholderTarget target = new TestPlaceholderTarget( - arch, - builder.Builder.GetMemoryContext().ReadFromTarget, - CreateContractTypes(builder)); - - IContractFactory cvfactory = new CodeVersionsFactory(); - ContractRegistry reg = Mock.Of( - c => c.CodeVersions == cvfactory.CreateContract(target, 1) - && c.RuntimeTypeSystem == mockRuntimeTypeSystem.Object - && c.ExecutionManager == mockExecutionManager.Object - && c.Loader == mockLoader.Object); - target.SetContracts(reg); - return target; + return new TestPlaceholderTarget.Builder(arch) + .UseReader(builder.Builder.GetMemoryContext().ReadFromTarget) + .AddTypes(CreateContractTypes(builder)) + .AddContract(version: 1) + .AddMockContract(mockRuntimeTypeSystem) + .AddMockContract(mockExecutionManager) + .AddMockContract(mockLoader) + .Build(); } [Theory] diff --git a/src/native/managed/cdac/tests/ContractDescriptor/ContractDescriptorBuilder.cs b/src/native/managed/cdac/tests/ContractDescriptor/ContractDescriptorBuilder.cs index c7961216806527..06af4e2d468f25 100644 --- a/src/native/managed/cdac/tests/ContractDescriptor/ContractDescriptorBuilder.cs +++ b/src/native/managed/cdac/tests/ContractDescriptor/ContractDescriptorBuilder.cs @@ -205,6 +205,6 @@ public bool TryCreateTarget(DescriptorBuilder descriptor, [NotNullWhen(true)] ou _created = true; ulong contractDescriptorAddress = descriptor.CreateSubDescriptor(ContractDescriptorAddr, JsonDescriptorAddr, ContractPointerDataAddr); MockMemorySpace.MemoryContext memoryContext = GetMemoryContext(); - return ContractDescriptorTarget.TryCreate(contractDescriptorAddress, memoryContext.ReadFromTarget, memoryContext.WriteToTarget, null, [], out target); + return ContractDescriptorTarget.TryCreate(contractDescriptorAddress, memoryContext.ReadFromTarget, memoryContext.WriteToTarget, (_, _, _) => throw new NotImplementedException("Tests do not provide GetTargetThreadContext"), [Contracts.CoreCLRContracts.Register], out target); } } diff --git a/src/native/managed/cdac/tests/DacStreamsTests.cs b/src/native/managed/cdac/tests/DacStreamsTests.cs index c104a33bca325b..792e952c60612a 100644 --- a/src/native/managed/cdac/tests/DacStreamsTests.cs +++ b/src/native/managed/cdac/tests/DacStreamsTests.cs @@ -1,11 +1,10 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Text; using Microsoft.Diagnostics.DataContractReader.Contracts; -using Moq; using Xunit; namespace Microsoft.Diagnostics.DataContractReader.Tests; @@ -35,16 +34,18 @@ private static readonly (string Name, ulong Value)[] DacStreamsGlobals = private static unsafe void DacStreamsContractHelper(MockTarget.Architecture arch, ConfigureContextBuilder configure, Action testCase) { - TargetTestHelpers targetTestHelpers = new(arch); - MockMemorySpace.Builder builder = new(targetTestHelpers); + var targetBuilder = new TestPlaceholderTarget.Builder(arch); + MockMemorySpace.Builder builder = targetBuilder.MemoryBuilder; if (configure != null) { builder = configure(builder); } - var target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget, DacStreamsTypes, DacStreamsGlobals); - target.SetContracts(Mock.Of( - c => c.DacStreams == ((IContractFactory)new DacStreamsFactory()).CreateContract(target, 1))); + var target = targetBuilder + .AddTypes(DacStreamsTypes) + .AddGlobals(DacStreamsGlobals) + .AddContract(version: 1) + .Build(); testCase(target); } diff --git a/src/native/managed/cdac/tests/DebuggerTests.cs b/src/native/managed/cdac/tests/DebuggerTests.cs index 3ad7c18f6e507f..a1526abeb941c7 100644 --- a/src/native/managed/cdac/tests/DebuggerTests.cs +++ b/src/native/managed/cdac/tests/DebuggerTests.cs @@ -65,7 +65,7 @@ private static TestPlaceholderTarget BuildTarget( builder.AddGlobals((Constants.Globals.MetadataUpdatesApplied, metadataFrag.Address)); } - builder.AddContract(target => ((IContractFactory)new DebuggerFactory()).CreateContract(target, 1)); + builder.AddContract(version: 1); return builder.Build(); } @@ -82,7 +82,7 @@ private static TestPlaceholderTarget BuildNullDebuggerTarget(MockTarget.Architec helpers.WritePointer(debuggerPtrFrag.Data, 0); memBuilder.AddHeapFragment(debuggerPtrFrag); builder.AddGlobals((Constants.Globals.Debugger, debuggerPtrFrag.Address)); - builder.AddContract(target => ((IContractFactory)new DebuggerFactory()).CreateContract(target, 1)); + builder.AddContract(version: 1); return builder.Build(); } diff --git a/src/native/managed/cdac/tests/DumpTests/DumpTestBase.cs b/src/native/managed/cdac/tests/DumpTests/DumpTestBase.cs index a4a8bd7b306376..1b9a9de0e9e087 100644 --- a/src/native/managed/cdac/tests/DumpTests/DumpTestBase.cs +++ b/src/native/managed/cdac/tests/DumpTests/DumpTestBase.cs @@ -106,7 +106,7 @@ protected void InitializeDumpTest(TestConfiguration config, string debuggeeName, _host.ReadFromTarget, writeToTarget: static (_, _) => -1, _host.GetThreadContext, - additionalFactories: [], + [Contracts.CoreCLRContracts.Register], out _target); Assert.True(created, $"Failed to create ContractDescriptorTarget from dump: {dumpPath}"); diff --git a/src/native/managed/cdac/tests/ExecutionManager/ExecutionManagerTests.cs b/src/native/managed/cdac/tests/ExecutionManager/ExecutionManagerTests.cs index 92db92922721c0..0affd3c288abf2 100644 --- a/src/native/managed/cdac/tests/ExecutionManager/ExecutionManagerTests.cs +++ b/src/native/managed/cdac/tests/ExecutionManager/ExecutionManagerTests.cs @@ -42,14 +42,13 @@ public class ExecutionManagerTests private static Target CreateTarget(MockExecutionManagerBuilder emBuilder) { var arch = emBuilder.Builder.TargetTestHelpers.Arch; - TestPlaceholderTarget.ReadFromTargetDelegate reader = emBuilder.Builder.GetMemoryContext().ReadFromTarget; - var target = new TestPlaceholderTarget(arch, reader, CreateContractTypes(emBuilder), emBuilder.Globals); - IContractFactory emfactory = new ExecutionManagerFactory(); - ContractRegistry reg = Mock.Of( - c => c.ExecutionManager == emfactory.CreateContract(target, emBuilder.Version) - && c.PlatformMetadata == new Mock().Object); - target.SetContracts(reg); - return target; + return new TestPlaceholderTarget.Builder(arch) + .UseReader(emBuilder.Builder.GetMemoryContext().ReadFromTarget) + .AddTypes(CreateContractTypes(emBuilder)) + .AddGlobals(emBuilder.Globals) + .AddContract(version: emBuilder.Version) + .AddMockContract(Mock.Of()) + .Build(); } private static IExecutionManager CreateExecutionManagerContract( diff --git a/src/native/managed/cdac/tests/ExecutionManager/RuntimeFunctionTests.cs b/src/native/managed/cdac/tests/ExecutionManager/RuntimeFunctionTests.cs index 4f8ab98449b35b..de66532243e05f 100644 --- a/src/native/managed/cdac/tests/ExecutionManager/RuntimeFunctionTests.cs +++ b/src/native/managed/cdac/tests/ExecutionManager/RuntimeFunctionTests.cs @@ -41,10 +41,10 @@ public void GetFunctionLength(MockTarget.Architecture arch, bool includeEndAddre uint[] entries = [0x100, 0x1f0, 0x1000, 0x2000, 0xa000]; TargetPointer addr = runtimeFunctions.AddRuntimeFunctions(entries); - Target target = new TestPlaceholderTarget( - builder.TargetTestHelpers.Arch, - builder.GetMemoryContext().ReadFromTarget, - CreateContractTypes(runtimeFunctions)); + Target target = new TestPlaceholderTarget.Builder(builder.TargetTestHelpers.Arch) + .UseReader(builder.GetMemoryContext().ReadFromTarget) + .AddTypes(CreateContractTypes(runtimeFunctions)) + .Build(); RuntimeFunctionLookup lookup = RuntimeFunctionLookup.Create(target); for (uint i = 0; i < entries.Length; i++) @@ -69,13 +69,11 @@ public void TryGetRuntimeFunctionIndexForAddress(MockTarget.Architecture arch) uint[] entries = [0x100, 0x1f0, 0x1000, 0x2000, 0xa000]; TargetPointer addr = runtimeFunctions.AddRuntimeFunctions(entries); - TestPlaceholderTarget target = new TestPlaceholderTarget( - builder.TargetTestHelpers.Arch, - builder.GetMemoryContext().ReadFromTarget, - CreateContractTypes(runtimeFunctions)); - ContractRegistry reg = Mock.Of( - c => c.PlatformMetadata == new Mock().Object); - target.SetContracts(reg); + TestPlaceholderTarget target = new TestPlaceholderTarget.Builder(builder.TargetTestHelpers.Arch) + .UseReader(builder.GetMemoryContext().ReadFromTarget) + .AddTypes(CreateContractTypes(runtimeFunctions)) + .AddMockContract(new Mock()) + .Build(); RuntimeFunctionLookup lookup = RuntimeFunctionLookup.Create(target); for (uint i = 0; i < entries.Length; i++) @@ -97,13 +95,11 @@ public void TryGetRuntimeFunctionIndexForAddress_NoMatch(MockTarget.Architecture uint[] entries = [0x100, 0x1f0]; TargetPointer addr = runtimeFunctions.AddRuntimeFunctions(entries); - TestPlaceholderTarget target = new TestPlaceholderTarget( - builder.TargetTestHelpers.Arch, - builder.GetMemoryContext().ReadFromTarget, - CreateContractTypes(runtimeFunctions)); - ContractRegistry reg = Mock.Of( - c => c.PlatformMetadata == new Mock().Object); - target.SetContracts(reg); + TestPlaceholderTarget target = new TestPlaceholderTarget.Builder(builder.TargetTestHelpers.Arch) + .UseReader(builder.GetMemoryContext().ReadFromTarget) + .AddTypes(CreateContractTypes(runtimeFunctions)) + .AddMockContract(new Mock()) + .Build(); RuntimeFunctionLookup lookup = RuntimeFunctionLookup.Create(target); TargetPointer relativeAddress = 0x0ff; diff --git a/src/native/managed/cdac/tests/GCMemoryRegionTests.cs b/src/native/managed/cdac/tests/GCMemoryRegionTests.cs index ac61e8e9f8e6af..d0d4b7d84f6587 100644 --- a/src/native/managed/cdac/tests/GCMemoryRegionTests.cs +++ b/src/native/managed/cdac/tests/GCMemoryRegionTests.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using Microsoft.Diagnostics.DataContractReader.Contracts; -using Moq; using Xunit; namespace Microsoft.Diagnostics.DataContractReader.Tests; @@ -25,11 +24,14 @@ private static IGC CreateGCContract(MockTarget.Architecture arch, (string Name, string Value)[] globalStrings, TestPlaceholderTarget.ReadFromTargetDelegate readFromTarget) { - var target = new TestPlaceholderTarget(arch, readFromTarget, types, globals, globalStrings); - var gcContract = ((IContractFactory)new GCFactory()).CreateContract(target, 1); - target.SetContracts(Mock.Of( - c => c.GC == gcContract)); - return gcContract; + var target = new TestPlaceholderTarget.Builder(arch) + .UseReader(readFromTarget) + .AddTypes(types) + .AddGlobals(globals) + .AddGlobalStrings(globalStrings) + .AddContract(version: 1) + .Build(); + return target.Contracts.GC; } private static (string Name, ulong Value)[] BuildGlobals( diff --git a/src/native/managed/cdac/tests/GCTests.cs b/src/native/managed/cdac/tests/GCTests.cs index bd5a95b1bf2492..feadcba74e3bbc 100644 --- a/src/native/managed/cdac/tests/GCTests.cs +++ b/src/native/managed/cdac/tests/GCTests.cs @@ -142,8 +142,7 @@ public static TestPlaceholderTarget.Builder AddGCHeapWks( GCHeapBuilder config = new(); configure(config); BuildWksHeap(targetBuilder, config); - targetBuilder.AddContract(target => - ((IContractFactory)new GCFactory()).CreateContract(target, 1)); + targetBuilder.AddContract(version: 1); return targetBuilder; } @@ -155,8 +154,7 @@ public static TestPlaceholderTarget.Builder AddGCHeapSvr( GCHeapBuilder config = new(); configure(config); heapAddress = BuildSvrHeap(targetBuilder, config); - targetBuilder.AddContract(target => - ((IContractFactory)new GCFactory()).CreateContract(target, 1)); + targetBuilder.AddContract(version: 1); return targetBuilder; } diff --git a/src/native/managed/cdac/tests/GetRegisterNameTests.cs b/src/native/managed/cdac/tests/GetRegisterNameTests.cs index 6aed07e9fc72ba..b7fac46e643fc6 100644 --- a/src/native/managed/cdac/tests/GetRegisterNameTests.cs +++ b/src/native/managed/cdac/tests/GetRegisterNameTests.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using Microsoft.Diagnostics.DataContractReader.Contracts; using Microsoft.Diagnostics.DataContractReader.Legacy; -using Moq; using Xunit; namespace Microsoft.Diagnostics.DataContractReader.Tests; @@ -16,18 +15,10 @@ private static SOSDacImpl CreateSosDacImpl( MockTarget.Architecture arch, RuntimeInfoArchitecture targetArch) { - MockMemorySpace.Builder builder = new MockMemorySpace.Builder(new TargetTestHelpers(arch)); - TestPlaceholderTarget target = new TestPlaceholderTarget( - arch, - builder.GetMemoryContext().ReadFromTarget, - [], - [], - [(Constants.Globals.Architecture, targetArch.ToString().ToLowerInvariant())]); - - IContractFactory runtimeInfoFactory = new RuntimeInfoFactory(); - ContractRegistry reg = Mock.Of( - c => c.RuntimeInfo == runtimeInfoFactory.CreateContract(target, 1)); - target.SetContracts(reg); + var target = new TestPlaceholderTarget.Builder(arch) + .AddGlobalStrings((Constants.Globals.Architecture, targetArch.ToString().ToLowerInvariant())) + .AddContract(version: 1) + .Build(); return new SOSDacImpl(target, legacyObj: null); } diff --git a/src/native/managed/cdac/tests/LoaderTests.cs b/src/native/managed/cdac/tests/LoaderTests.cs index 6d41303125eeaa..c63b89be8b79c7 100644 --- a/src/native/managed/cdac/tests/LoaderTests.cs +++ b/src/native/managed/cdac/tests/LoaderTests.cs @@ -24,15 +24,15 @@ public unsafe class LoaderTests private static ILoader CreateLoaderContract(MockTarget.Architecture arch, Action configure) { - TargetTestHelpers helpers = new(arch); - MockMemorySpace.Builder builder = new(helpers); - MockLoaderBuilder loader = new(builder); + var targetBuilder = new TestPlaceholderTarget.Builder(arch); + MockLoaderBuilder loader = new(targetBuilder.MemoryBuilder); configure(loader); - var target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget, CreateContractTypes(loader)); - target.SetContracts(Mock.Of( - c => c.Loader == ((IContractFactory)new LoaderFactory()).CreateContract(target, 1))); + var target = targetBuilder + .AddTypes(CreateContractTypes(loader)) + .AddContract(version: 1) + .Build(); return target.Contracts.Loader; } @@ -147,9 +147,8 @@ public void TryGetSimpleName_InvalidUtf8(MockTarget.Architecture arch) private static ISOSDacInterface13 CreateSOSDacInterface13ForHeapTests(MockTarget.Architecture arch) { - TargetTestHelpers helpers = new(arch); - MockMemorySpace.Builder builder = new(helpers); - MockLoaderBuilder loader = new(builder); + var targetBuilder = new TestPlaceholderTarget.Builder(arch); + MockLoaderBuilder loader = new(targetBuilder.MemoryBuilder); var types = new Dictionary(CreateContractTypes(loader)); // Register LoaderAllocator and VirtualCallStubManager type infos so that @@ -177,11 +176,12 @@ private static ISOSDacInterface13 CreateSOSDacInterface13ForHeapTests(MockTarget } }; - var target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget, types); - target.SetContracts(Mock.Of( - c => c.Loader == Mock.Of( + var target = targetBuilder + .AddTypes(types) + .AddMockContract(Mock.Of( l => l.GetLoaderAllocatorHeaps(It.IsAny()) == (IReadOnlyDictionary)MockHeapDictionary - && l.GetGlobalLoaderAllocator() == new TargetPointer(0x100)))); + && l.GetGlobalLoaderAllocator() == new TargetPointer(0x100))) + .Build(); return new SOSDacImpl(target, null); } @@ -325,7 +325,8 @@ private static (TestPlaceholderTarget Target, TargetPointer PEAssemblyAddr, Targ ushort versionMajor = 0) { TargetTestHelpers helpers = new(arch); - MockMemorySpace.Builder builder = new(helpers); + var targetBuilder = new TestPlaceholderTarget.Builder(arch); + MockMemorySpace.Builder builder = targetBuilder.MemoryBuilder; var allocator = builder.CreateAllocator(0x0010_0000, 0x0020_0000); var probeExtLayout = helpers.LayoutFields([ @@ -422,9 +423,10 @@ private static (TestPlaceholderTarget Target, TargetPointer PEAssemblyAddr, Targ helpers.WritePointer(peAssemblyFrag.Data.AsSpan().Slice(peAssemblyLayout.Fields[nameof(Data.PEAssembly.PEImage)].Offset, helpers.PointerSize), peImageFrag.Address); builder.AddHeapFragment(peAssemblyFrag); - var target = new TestPlaceholderTarget(arch, builder.GetMemoryContext().ReadFromTarget, types); - target.SetContracts(Mock.Of( - c => c.Loader == ((IContractFactory)new LoaderFactory()).CreateContract(target, 1))); + var target = targetBuilder + .AddTypes(types) + .AddContract(version: 1) + .Build(); return (target, new TargetPointer(peAssemblyFrag.Address), new TargetPointer(webcilImage.Address)); } diff --git a/src/native/managed/cdac/tests/MethodDescTests.cs b/src/native/managed/cdac/tests/MethodDescTests.cs index 6c6ccd4b2459b0..8cf05c2c2346b8 100644 --- a/src/native/managed/cdac/tests/MethodDescTests.cs +++ b/src/native/managed/cdac/tests/MethodDescTests.cs @@ -60,26 +60,22 @@ private static IRuntimeTypeSystem CreateRuntimeTypeSystemContract( Action configure, Mock? mockExecutionManager = null) { - TargetTestHelpers helpers = new(arch); - MockMemorySpace.Builder builder = new(helpers); - MockDescriptors.RuntimeTypeSystem rtsBuilder = new(builder); - MockLoaderBuilder loaderBuilder = new(builder); + var targetBuilder = new TestPlaceholderTarget.Builder(arch); + MockDescriptors.RuntimeTypeSystem rtsBuilder = new(targetBuilder.MemoryBuilder); + MockLoaderBuilder loaderBuilder = new(targetBuilder.MemoryBuilder); MockDescriptors.MockMethodDescriptorsBuilder methodDescBuilder = new(rtsBuilder, loaderBuilder); configure(methodDescBuilder); - var target = new TestPlaceholderTarget( - builder.TargetTestHelpers.Arch, - builder.GetMemoryContext().ReadFromTarget, - CreateContractTypes(methodDescBuilder), - CreateContractGlobals(methodDescBuilder)); - mockExecutionManager ??= new Mock(); - target.SetContracts(Mock.Of( - c => c.RuntimeTypeSystem == ((IContractFactory)new RuntimeTypeSystemFactory()).CreateContract(target, 1) - && c.Loader == ((IContractFactory)new LoaderFactory()).CreateContract(target, 1) - && c.PlatformMetadata == new Mock().Object - && c.ExecutionManager == mockExecutionManager.Object)); + var target = targetBuilder + .AddTypes(CreateContractTypes(methodDescBuilder)) + .AddGlobals(CreateContractGlobals(methodDescBuilder)) + .AddContract(version: 1) + .AddContract(version: 1) + .AddMockContract(new Mock()) + .AddMockContract(mockExecutionManager) + .Build(); return target.Contracts.RuntimeTypeSystem; } diff --git a/src/native/managed/cdac/tests/MethodTableTests.cs b/src/native/managed/cdac/tests/MethodTableTests.cs index 02028bcf5cf073..62c16a9fac486f 100644 --- a/src/native/managed/cdac/tests/MethodTableTests.cs +++ b/src/native/managed/cdac/tests/MethodTableTests.cs @@ -7,7 +7,6 @@ using Microsoft.Diagnostics.DataContractReader.Contracts; using Microsoft.Diagnostics.DataContractReader.Legacy; using Microsoft.Diagnostics.DataContractReader.RuntimeTypeSystemHelpers; -using Moq; using Xunit; using static Microsoft.Diagnostics.DataContractReader.Tests.TestHelpers; @@ -41,19 +40,16 @@ internal static (string Name, ulong Value)[] CreateContractGlobals(MockRTS rtsBu internal static TestPlaceholderTarget CreateTarget(MockTarget.Architecture arch, Action configure) { - TargetTestHelpers targetTestHelpers = new(arch); - MockMemorySpace.Builder builder = new(targetTestHelpers); - MockRTS rtsBuilder = new(builder); + var targetBuilder = new TestPlaceholderTarget.Builder(arch); + MockRTS rtsBuilder = new(targetBuilder.MemoryBuilder); configure?.Invoke(rtsBuilder); - var target = new TestPlaceholderTarget( - arch, - builder.GetMemoryContext().ReadFromTarget, - CreateContractTypes(rtsBuilder), - CreateContractGlobals(rtsBuilder)); - target.SetContracts(Mock.Of( - c => c.RuntimeTypeSystem == ((IContractFactory)new RuntimeTypeSystemFactory()).CreateContract(target, 1))); + var target = targetBuilder + .AddTypes(CreateContractTypes(rtsBuilder)) + .AddGlobals(CreateContractGlobals(rtsBuilder)) + .AddContract(version: 1) + .Build(); return target; } diff --git a/src/native/managed/cdac/tests/NotificationsTests.cs b/src/native/managed/cdac/tests/NotificationsTests.cs index fee954541100f5..ee4fd730f5b800 100644 --- a/src/native/managed/cdac/tests/NotificationsTests.cs +++ b/src/native/managed/cdac/tests/NotificationsTests.cs @@ -18,8 +18,11 @@ public class NotificationsTests private static INotifications CreateContract() { - var target = new TestPlaceholderTarget(new MockTarget.Architecture { IsLittleEndian = true, Is64Bit = true }, (_, _) => -1); - return ((IContractFactory)new NotificationsFactory()).CreateContract(target, 1); + var target = new TestPlaceholderTarget.Builder(new MockTarget.Architecture { IsLittleEndian = true, Is64Bit = true }) + .UseReader((_, _) => -1) + .AddContract(version: 1) + .Build(); + return target.Contracts.Notifications; } private static ReadOnlySpan MakeExInfo(params ulong[] values) diff --git a/src/native/managed/cdac/tests/ObjectTests.cs b/src/native/managed/cdac/tests/ObjectTests.cs index 63ffa8ea78e02b..addc839714350f 100644 --- a/src/native/managed/cdac/tests/ObjectTests.cs +++ b/src/native/managed/cdac/tests/ObjectTests.cs @@ -19,29 +19,37 @@ private static IObject CreateObjectContract(MockTarget.Architecture arch, Action private static ISOSDacInterface CreateSOSDacInterface( MockTarget.Architecture arch, Action configure, - Func? createContracts = null) - => new SOSDacImpl(CreateObjectTarget(arch, configure, createContracts), legacyObj: null); + Action? configureMocks = null) + => new SOSDacImpl(CreateObjectTarget(arch, configure, configureMocks), legacyObj: null); private static TestPlaceholderTarget CreateObjectTarget( MockTarget.Architecture arch, Action configure, - Func? createContracts = null) + Action? configureMocks = null) { - TargetTestHelpers targetTestHelpers = new(arch); - - MockMemorySpace.Builder builder = new(targetTestHelpers); - MockDescriptors.RuntimeTypeSystem rtsBuilder = new(builder); + var targetBuilder = new TestPlaceholderTarget.Builder(arch); + MockDescriptors.RuntimeTypeSystem rtsBuilder = new(targetBuilder.MemoryBuilder); MockDescriptors.MockObjectBuilder objectBuilder = new(rtsBuilder); configure?.Invoke(objectBuilder); - var target = new TestPlaceholderTarget( - arch, - builder.GetMemoryContext().ReadFromTarget, - CreateContractTypes(objectBuilder), - CreateContractGlobals(objectBuilder)); - target.SetContracts(createContracts?.Invoke(target) ?? CreateDefaultContracts(target)); - return target; + targetBuilder + .AddTypes(CreateContractTypes(objectBuilder)) + .AddGlobals(CreateContractGlobals(objectBuilder)); + + if (configureMocks is not null) + { + configureMocks(targetBuilder); + } + else + { + targetBuilder + .AddContract(version: 1) + .AddContract(version: 1) + .AddContract(version: 1); + } + + return targetBuilder.Build(); } private static Dictionary CreateContractTypes(MockDescriptors.MockObjectBuilder objectBuilder) @@ -70,12 +78,6 @@ private static (string Name, ulong Value)[] CreateContractGlobals(MockDescriptor (nameof(Constants.Globals.SyncBlockHashCodeMask), (1u << 26) - 1), ]).ToArray(); - private static ContractRegistry CreateDefaultContracts(TestPlaceholderTarget target) - => Mock.Of( - c => c.Object == ((IContractFactory)new ObjectFactory()).CreateContract(target, 1) - && c.RuntimeTypeSystem == ((IContractFactory)new RuntimeTypeSystemFactory()).CreateContract(target, 1) - && c.SyncBlock == ((IContractFactory)new SyncBlockFactory()).CreateContract(target, 1)); - [Theory] [ClassData(typeof(MockTarget.StdArch))] public void UnmaskMethodTableAddress(MockTarget.Architecture arch) @@ -227,7 +229,7 @@ public void GetObjectClassName_UnloadedModule(MockTarget.Architecture arch) methodTable.EEClassOrCanonMT = eeClass.Address; TestObjectAddress = objectBuilder.AddObject(TestMethodTableAddress); }, - target => { + builder => { var mockRts = new Mock(); TypeHandle handle = new TypeHandle(TestMethodTableAddress); mockRts.Setup(r => r.GetTypeHandle(TestMethodTableAddress)).Returns(handle); @@ -240,10 +242,10 @@ public void GetObjectClassName_UnloadedModule(MockTarget.Architecture arch) var mockObject = new Mock(); mockObject.Setup(o => o.GetMethodTableAddress(It.IsAny())).Returns(TestMethodTableAddress); - return Mock.Of( - c => c.Object == mockObject.Object - && c.RuntimeTypeSystem == mockRts.Object - && c.Loader == mockLoader.Object); + builder + .AddMockContract(mockObject) + .AddMockContract(mockRts) + .AddMockContract(mockLoader); }); char[] buffer = new char[256]; uint needed; @@ -275,7 +277,7 @@ public void GetObjectClassName_NullBufferReturnsNeededSize(MockTarget.Architectu methodTable.EEClassOrCanonMT = eeClass.Address; TestObjectAddress = objectBuilder.AddObject(TestMethodTableAddress); }, - target => { + builder => { var mockRts = new Mock(); TypeHandle handle = new TypeHandle(TestMethodTableAddress); mockRts.Setup(r => r.GetTypeHandle(TestMethodTableAddress)).Returns(handle); @@ -288,10 +290,10 @@ public void GetObjectClassName_NullBufferReturnsNeededSize(MockTarget.Architectu var mockObject = new Mock(); mockObject.Setup(o => o.GetMethodTableAddress(It.IsAny())).Returns(TestMethodTableAddress); - return Mock.Of( - c => c.Object == mockObject.Object - && c.RuntimeTypeSystem == mockRts.Object - && c.Loader == mockLoader.Object); + builder + .AddMockContract(mockObject) + .AddMockContract(mockRts) + .AddMockContract(mockLoader); }); uint needed; int hr = sosDac.GetObjectClassName(new ClrDataAddress(TestObjectAddress.Value), 0, null, &needed); diff --git a/src/native/managed/cdac/tests/PrecodeStubsTests.cs b/src/native/managed/cdac/tests/PrecodeStubsTests.cs index a5b6c9fea5e15f..30adbc3f82ae65 100644 --- a/src/native/managed/cdac/tests/PrecodeStubsTests.cs +++ b/src/native/managed/cdac/tests/PrecodeStubsTests.cs @@ -359,22 +359,19 @@ public TargetCodePointer AddThisPtrRetBufPrecodeEntry(string name, PrecodeTestDe private static Target CreateTarget(PrecodeBuilder precodeBuilder) { var arch = precodeBuilder.Builder.TargetTestHelpers.Arch; - TestPlaceholderTarget.ReadFromTargetDelegate reader = precodeBuilder.Builder.GetMemoryContext().ReadFromTarget; - // hack for this test put the precode machine descriptor at the same address as the PlatformMetadata (string Name, ulong Value)[] globals = [(Constants.Globals.PlatformMetadata, precodeBuilder.MachineDescriptorAddress)]; - var target = new TestPlaceholderTarget(arch, reader, precodeBuilder.Types, globals); - IContractFactory precodeFactory = new PrecodeStubsFactory(); Mock platformMetadata = new(); platformMetadata.Setup(p => p.GetCodePointerFlags()).Returns(precodeBuilder.CodePointerFlags); platformMetadata.Setup(p => p.GetPrecodeMachineDescriptor()).Returns(precodeBuilder.MachineDescriptorAddress); - // Creating the PrecodeStubs contract depends on the PlatformMetadata contract, so we need - // to set it up such that it will only be created after the target's targets are set up - Mock reg = new(); - reg.SetupGet(c => c.PlatformMetadata).Returns(platformMetadata.Object); - reg.SetupGet(c => c.PrecodeStubs).Returns(() => precodeFactory.CreateContract(target, precodeBuilder.PrecodesVersion)); - target.SetContracts(reg.Object); + var target = new TestPlaceholderTarget.Builder(arch) + .UseReader(precodeBuilder.Builder.GetMemoryContext().ReadFromTarget) + .AddTypes(precodeBuilder.Types) + .AddGlobals(globals) + .AddMockContract(platformMetadata) + .AddContract(version: precodeBuilder.PrecodesVersion) + .Build(); return target; } diff --git a/src/native/managed/cdac/tests/ReJITTests.cs b/src/native/managed/cdac/tests/ReJITTests.cs index a79896e0f7da20..5024ac44323100 100644 --- a/src/native/managed/cdac/tests/ReJITTests.cs +++ b/src/native/managed/cdac/tests/ReJITTests.cs @@ -40,8 +40,8 @@ private static ReJITContractContext CreateReJITContract( TestPlaceholderTarget target = targetBuilder .AddTypes(CreateContractTypes(rejitBuilder)) .AddGlobals((nameof(Constants.Globals.ProfilerControlBlock), rejitBuilder.ProfilerControlBlockGlobalAddress)) - .AddContract(static target => ((IContractFactory)new ReJITFactory()).CreateContract(target, 1)) - .AddContract(_ => mockCodeVersions.Object) + .AddContract(version: 1) + .AddMockContract(mockCodeVersions) .Build(); return new ReJITContractContext(target.Contracts.ReJIT, target); } diff --git a/src/native/managed/cdac/tests/RuntimeInfoTests.cs b/src/native/managed/cdac/tests/RuntimeInfoTests.cs index 9ca60b10f45e29..b4ef18c250deb9 100644 --- a/src/native/managed/cdac/tests/RuntimeInfoTests.cs +++ b/src/native/managed/cdac/tests/RuntimeInfoTests.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using Microsoft.Diagnostics.DataContractReader.Contracts; -using Moq; using Xunit; namespace Microsoft.Diagnostics.DataContractReader.Tests; @@ -16,19 +15,13 @@ internal static Target CreateTarget( (string Name, string Value)[] globalStrings, (string Name, ulong Value)[]? globals = null) { - MockMemorySpace.Builder builder = new(new TargetTestHelpers(arch)); - TestPlaceholderTarget target = new( - arch, - builder.GetMemoryContext().ReadFromTarget, - [], - globals, - globalStrings); - - IContractFactory runtimeInfoFactory = new RuntimeInfoFactory(); - ContractRegistry reg = Mock.Of( - c => c.RuntimeInfo == runtimeInfoFactory.CreateContract(target, 1)); - target.SetContracts(reg); - return target; + var builder = new TestPlaceholderTarget.Builder(arch); + if (globals is not null) + builder.AddGlobals(globals); + return builder + .AddGlobalStrings(globalStrings) + .AddContract(version: 1) + .Build(); } public static IEnumerable StdArchAllTargetArchitectures() diff --git a/src/native/managed/cdac/tests/SOSDacInterface5Tests.cs b/src/native/managed/cdac/tests/SOSDacInterface5Tests.cs index 7677152b38f48c..745c1609acfc18 100644 --- a/src/native/managed/cdac/tests/SOSDacInterface5Tests.cs +++ b/src/native/managed/cdac/tests/SOSDacInterface5Tests.cs @@ -104,15 +104,13 @@ private static ISOSDacInterface5 CreateDac5( .Setup(c => c.GetNativeCodeVersions(s_methodDescAddr, It.IsAny())) .Returns(nativeVersionHandles); - var target = new TestPlaceholderTarget( - arch, - (_, _) => -1, - types: []); - target.SetContracts(Mock.Of( - c => c.CodeVersions == mockCodeVersions.Object - && c.RuntimeTypeSystem == mockRts.Object - && c.Loader == mockLoader.Object - && c.ReJIT == mockReJIT.Object)); + var target = new TestPlaceholderTarget.Builder(arch) + .UseReader((_, _) => -1) + .AddMockContract(mockCodeVersions) + .AddMockContract(mockRts) + .AddMockContract(mockLoader) + .AddMockContract(mockReJIT) + .Build(); return new SOSDacImpl(target, legacyObj: null); } diff --git a/src/native/managed/cdac/tests/SyncBlockTests.cs b/src/native/managed/cdac/tests/SyncBlockTests.cs index f1326c4cba0fc2..d596047f0b1b6b 100644 --- a/src/native/managed/cdac/tests/SyncBlockTests.cs +++ b/src/native/managed/cdac/tests/SyncBlockTests.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using Moq; using Xunit; using Microsoft.Diagnostics.DataContractReader.Contracts; @@ -14,20 +13,17 @@ public class SyncBlockTests { private static ISyncBlock CreateSyncBlockContract(MockTarget.Architecture arch, Action configure) { - TargetTestHelpers helpers = new(arch); - MockMemorySpace.Builder builder = new(helpers); - MockMemorySpace.BumpAllocator allocator = builder.CreateAllocator(0x0001_0000, 0x0002_0000); - MockSyncBlockBuilder syncBlock = new(builder, allocator); + var builder = new TestPlaceholderTarget.Builder(arch); + MockMemorySpace.BumpAllocator allocator = builder.MemoryBuilder.CreateAllocator(0x0001_0000, 0x0002_0000); + MockSyncBlockBuilder syncBlock = new(builder.MemoryBuilder, allocator); configure(syncBlock); - var target = new TestPlaceholderTarget( - arch, - builder.GetMemoryContext().ReadFromTarget, - CreateContractTypes(syncBlock), - CreateContractGlobals(syncBlock)); - target.SetContracts(Mock.Of( - c => c.SyncBlock == ((IContractFactory)new SyncBlockFactory()).CreateContract(target, 1))); + var target = builder + .AddTypes(CreateContractTypes(syncBlock)) + .AddGlobals(CreateContractGlobals(syncBlock)) + .AddContract(version: 1) + .Build(); return target.Contracts.SyncBlock; } diff --git a/src/native/managed/cdac/tests/TestPlaceholderTarget.cs b/src/native/managed/cdac/tests/TestPlaceholderTarget.cs index 2ba7c98187bffc..8e9fc73072acaf 100644 --- a/src/native/managed/cdac/tests/TestPlaceholderTarget.cs +++ b/src/native/managed/cdac/tests/TestPlaceholderTarget.cs @@ -8,6 +8,7 @@ using System.Runtime.CompilerServices; using System.Text; using Microsoft.Diagnostics.DataContractReader.Contracts; +using Moq; namespace Microsoft.Diagnostics.DataContractReader.Tests; @@ -45,6 +46,22 @@ internal void SetContracts(ContractRegistry contracts) _contractRegistry = contracts; } + /// + /// Creates a with the given registration action + /// (defaulting to ), and sets it as the + /// contract registry for this target. Returns the registry so callers can call + /// and + /// . + /// + internal TestContractRegistry SetupContractRegistry(Action? registrations = null) + { + var registry = new TestContractRegistry(); + registry.SetTarget(this); + (registrations ?? CoreCLRContracts.Register)(registry); + _contractRegistry = registry; + return registry; + } + /// /// Fluent builder for . Accumulates types, /// globals, and contract factories from mock descriptors, then materializes the @@ -57,7 +74,9 @@ internal class Builder private readonly Dictionary _types = new(); private readonly List<(string Name, ulong Value)> _globals = new(); private readonly List<(string Name, string Value)> _globalStrings = new(); - private readonly List<(Type Type, Func Factory)> _contractFactories = new(); + private readonly List> _contractSetups = new(); + private Action _registrations = CoreCLRContracts.Register; + private ReadFromTargetDelegate? _readerOverride; public Builder(MockTarget.Architecture arch) { @@ -86,9 +105,33 @@ public Builder AddGlobalStrings(params (string Name, string Value)[] globalStrin return this; } - public Builder AddContract(Func factory) where TContract : IContract + public Builder UseReader(ReadFromTargetDelegate reader) + { + _readerOverride = reader; + return this; + } + + public Builder UseRegistrations(Action registrations) + { + _registrations = registrations; + return this; + } + + public Builder AddContract(int version) where TContract : IContract + { + _contractSetups.Add(registry => registry.SetVersion(version)); + return this; + } + + public Builder AddMockContract(TContract mock) where TContract : IContract { - _contractFactories.Add((typeof(TContract), target => factory(target))); + _contractSetups.Add(registry => registry.SetMock(mock)); + return this; + } + + public Builder AddMockContract(Mock mock) where TContract : class, IContract + { + _contractSetups.Add(registry => registry.SetMock(mock.Object)); return this; } @@ -96,14 +139,18 @@ public TestPlaceholderTarget Build() { var target = new TestPlaceholderTarget( _arch, - _memBuilder.GetMemoryContext().ReadFromTarget, + _readerOverride ?? _memBuilder.GetMemoryContext().ReadFromTarget, _types, _globals.ToArray(), _globalStrings.ToArray()); var registry = new TestContractRegistry(); - foreach (var (type, factory) in _contractFactories) - registry.Add(type, new Lazy(() => factory(target))); + registry.SetTarget(target); + _registrations(registry); + + foreach (var setup in _contractSetups) + setup(registry); + target.SetContracts(registry); return target; @@ -455,18 +502,49 @@ public void Clear() } } - private sealed class TestContractRegistry : ContractRegistry + internal sealed class TestContractRegistry : ContractRegistry { - private readonly Dictionary> _contracts = new(); + private readonly Dictionary<(Type, int), Func> _creators = new(); + private readonly Dictionary _versions = new(); + private readonly Dictionary _mocks = new(); + private readonly Dictionary _resolved = new(); + private Target _target = null!; + + public void SetTarget(Target target) => _target = target; + + public void SetVersion(int version) where TContract : IContract + => _versions[typeof(TContract)] = version; + + public void SetMock(TContract mock) where TContract : IContract + => _mocks[typeof(TContract)] = mock; - public void Add(Type type, Lazy contract) => _contracts[type] = contract; + public override void Register(int version, Func creator) + => _creators[(typeof(TContract), version)] = t => creator(t); public override TContract GetContract() { - if (_contracts.TryGetValue(typeof(TContract), out var lazy)) - return (TContract)lazy.Value; + if (_resolved.TryGetValue(typeof(TContract), out var cached)) + return (TContract)cached; + + IContract contract; + if (_mocks.TryGetValue(typeof(TContract), out var mock)) + { + contract = mock; + } + else if (_versions.TryGetValue(typeof(TContract), out int version)) + { + if (!_creators.TryGetValue((typeof(TContract), version), out var creator)) + throw new NotImplementedException($"No implementation registered for contract '{typeof(TContract).Name}' version {version}."); + + contract = creator(_target); + } + else + { + throw new NotImplementedException($"Contract {typeof(TContract).Name} is not registered. Use SetVersion(version) or SetMock(mock) to configure contracts."); + } - throw new NotImplementedException($"Contract {typeof(TContract).Name} is not registered."); + _resolved[typeof(TContract)] = contract; + return (TContract)contract; } public override void Flush() { } diff --git a/src/native/managed/cdac/tests/ThreadTests.cs b/src/native/managed/cdac/tests/ThreadTests.cs index 8d51383fb882e0..af9a4df03f0d80 100644 --- a/src/native/managed/cdac/tests/ThreadTests.cs +++ b/src/native/managed/cdac/tests/ThreadTests.cs @@ -25,7 +25,7 @@ private static TestPlaceholderTarget CreateTarget( (nameof(Constants.Globals.ThreadStore), threadBuilder.ThreadStoreGlobalAddress), (nameof(Constants.Globals.FinalizerThread), threadBuilder.FinalizerThreadGlobalAddress), (nameof(Constants.Globals.GCThread), threadBuilder.GCThreadGlobalAddress)) - .AddContract(static target => ((IContractFactory)new ThreadFactory()).CreateContract(target, 1)) + .AddContract(version: 1) .Build(); return target; diff --git a/src/tools/StressLogAnalyzer/src/Program.cs b/src/tools/StressLogAnalyzer/src/Program.cs index f1f10ea3ae4cd4..676b8d5ec46b92 100644 --- a/src/tools/StressLogAnalyzer/src/Program.cs +++ b/src/tools/StressLogAnalyzer/src/Program.cs @@ -354,12 +354,11 @@ private static async Task AnalyzeStressLog(Options options, CancellationTok } try { - (Func targetFactory, StressLogHeader.ModuleTable moduleTable, int contractVersion, TargetPointer logs) = CreateTarget(accessor.SafeMemoryMappedViewHandle); + (Func targetFactory, StressLogHeader.ModuleTable moduleTable, TargetPointer logs) = CreateTarget(accessor.SafeMemoryMappedViewHandle); Target globalTarget = targetFactory(); - StressLogFactory factory = new(); - IStressLog globalStressLogContract = factory.CreateContract(globalTarget, contractVersion); + IStressLog globalStressLogContract = globalTarget.Contracts.GetContract(); using TextWriter? outputFile = options.OutputFile is not null ? File.CreateText(options.OutputFile.FullName) : null; @@ -375,7 +374,7 @@ private static async Task AnalyzeStressLog(Options options, CancellationTok TimeTracker timeTracker = CreateTimeTracker(accessor.SafeMemoryMappedViewHandle, options); var analyzer = new StressLogAnalyzer( - () => factory.CreateContract(globalTarget, contractVersion), + globalTarget.Contracts.GetContract, stringFinder, messageFilter, options.ThreadFilter, @@ -472,7 +471,7 @@ private static IMessageFilter CreateMessageFilter(Options options, IInterestingS return filter; } - private static unsafe (Func targetFactory, StressLogHeader.ModuleTable table, int contractVersion, TargetPointer logs) CreateTarget(SafeMemoryMappedViewHandle handle) + private static unsafe (Func targetFactory, StressLogHeader.ModuleTable table, TargetPointer logs) CreateTarget(SafeMemoryMappedViewHandle handle) { byte* buffer = null; handle.AcquirePointer(ref buffer); @@ -487,7 +486,7 @@ private static unsafe (Func targetFactory, StressLogHeader.ModuleTable t int contractVersion = (int)(header->version & 0xFFFF); - return (CreateTarget, header->moduleTable, contractVersion, header->logs); + return (CreateTarget, header->moduleTable, header->logs); ContractDescriptorTarget CreateTarget() => ContractDescriptorTarget.Create( GetDescriptor(contractVersion), @@ -497,7 +496,7 @@ ContractDescriptorTarget CreateTarget() => ContractDescriptorTarget.Create( (threadId, contextFlags, bufferToFill) => throw new NotImplementedException("StressLogAnalyzer does not provide GetTargetThreadContext implementation"), true, nuint.Size, - []); + [CoreCLRContracts.Register]); } private static unsafe TimeTracker CreateTimeTracker(SafeMemoryMappedViewHandle handle, Options options)