diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractRegistry.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractRegistry.cs
new file mode 100644
index 00000000000000..930cb017814d17
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/ContractRegistry.cs
@@ -0,0 +1,42 @@
+// 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;
+
+
+namespace Microsoft.Diagnostics.DataContractReader;
+
+///
+/// A registry of all the contracts that may be provided by a target.
+///
+internal abstract class ContractRegistry
+{
+ ///
+ /// Gets an instance of the Exception contract for the target.
+ ///
+ public abstract IException Exception { get;}
+ ///
+ /// Gets an instance of the Loader contract for the target.
+ ///
+ public abstract ILoader Loader { get; }
+ ///
+ /// Gets an instance of the EcmaMetadata contract for the target.
+ ///
+ public abstract IEcmaMetadata EcmaMetadata { get; }
+ ///
+ /// Gets an instance of the Object contract for the target.
+ ///
+ public abstract IObject Object { get; }
+ ///
+ /// Gets an instance of the Thread contract for the target.
+ ///
+ public abstract IThread Thread { get; }
+ ///
+ /// Gets an instance of the RuntimeTypeSystem contract for the target.
+ ///
+ public abstract IRuntimeTypeSystem RuntimeTypeSystem { get; }
+ ///
+ /// Gets an instance of the DacStreams contract for the target.
+ ///
+ public abstract IDacStreams DacStreams { get; }
+}
diff --git a/src/native/managed/cdacreader/src/Contracts/IContract.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IContract.cs
similarity index 75%
rename from src/native/managed/cdacreader/src/Contracts/IContract.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IContract.cs
index 1a78ce2a429209..43dadfb923b3cc 100644
--- a/src/native/managed/cdacreader/src/Contracts/IContract.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IContract.cs
@@ -8,5 +8,4 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;
internal interface IContract
{
static virtual string Name => throw new NotImplementedException();
- static virtual IContract Create(Target target, int version) => throw new NotImplementedException();
}
diff --git a/src/native/managed/cdacreader/src/Contracts/DacStreams.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IDacStreams.cs
similarity index 55%
rename from src/native/managed/cdacreader/src/Contracts/DacStreams.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IDacStreams.cs
index 167c7f89ad2bfd..76c33b469aee77 100644
--- a/src/native/managed/cdacreader/src/Contracts/DacStreams.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IDacStreams.cs
@@ -1,26 +1,13 @@
-// 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.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace Microsoft.Diagnostics.DataContractReader.Contracts;
internal interface IDacStreams : IContract
{
static string IContract.Name { get; } = nameof(DacStreams);
- static IContract IContract.Create(Target target, int version)
- {
- return version switch
- {
- 1 => new DacStreams_1(target),
- _ => default(DacStreams),
- };
- }
-
public virtual string? StringFromEEAddress(TargetPointer address) => throw new NotImplementedException();
}
diff --git a/src/native/managed/cdacreader/src/Contracts/EcmaMetadata.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IEcmaMetadata.cs
similarity index 76%
rename from src/native/managed/cdacreader/src/Contracts/EcmaMetadata.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IEcmaMetadata.cs
index c7d8e5412b864e..d2fe21ff33823f 100644
--- a/src/native/managed/cdacreader/src/Contracts/EcmaMetadata.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IEcmaMetadata.cs
@@ -9,17 +9,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;
internal interface IEcmaMetadata : IContract
{
static string IContract.Name { get; } = nameof(EcmaMetadata);
- static IContract IContract.Create(Target target, int version)
- {
- return version switch
- {
- 1 => new EcmaMetadata_1(target),
- _ => default(EcmaMetadata),
- };
- }
-
public virtual TargetSpan GetReadOnlyMetadataAddress(ModuleHandle handle) => throw new NotImplementedException();
-
public virtual MetadataReader? GetMetadata(ModuleHandle module) => throw new NotImplementedException();
}
diff --git a/src/native/managed/cdacreader/src/Contracts/Exception.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IException.cs
similarity index 82%
rename from src/native/managed/cdacreader/src/Contracts/Exception.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IException.cs
index 2ad3d10faeb655..66c2af846cd8c3 100644
--- a/src/native/managed/cdacreader/src/Contracts/Exception.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IException.cs
@@ -18,14 +18,6 @@ internal record struct ExceptionData(
internal interface IException : IContract
{
static string IContract.Name { get; } = nameof(Exception);
- static IContract IContract.Create(Target target, int version)
- {
- return version switch
- {
- 1 => new Exception_1(target),
- _ => default(Exception),
- };
- }
public virtual TargetPointer GetNestedExceptionInfo(TargetPointer exception, out TargetPointer nextNestedException) => throw new NotImplementedException();
public virtual ExceptionData GetExceptionData(TargetPointer managedException) => throw new NotImplementedException();
diff --git a/src/native/managed/cdacreader/src/Contracts/Loader.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs
similarity index 90%
rename from src/native/managed/cdacreader/src/Contracts/Loader.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs
index a71bdd4d129515..4c3be1e2f0a8a5 100644
--- a/src/native/managed/cdacreader/src/Contracts/Loader.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/ILoader.cs
@@ -35,14 +35,6 @@ internal record struct ModuleLookupTables(
internal interface ILoader : IContract
{
static string IContract.Name => nameof(Loader);
- static IContract IContract.Create(Target target, int version)
- {
- return version switch
- {
- 1 => new Loader_1(target),
- _ => default(Loader),
- };
- }
public virtual ModuleHandle GetModuleHandle(TargetPointer modulePointer) => throw new NotImplementedException();
diff --git a/src/native/managed/cdacreader/src/Contracts/Object.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IObject.cs
similarity index 55%
rename from src/native/managed/cdacreader/src/Contracts/Object.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IObject.cs
index 944b97388b69ad..780ce9b4f1bdaa 100644
--- a/src/native/managed/cdacreader/src/Contracts/Object.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IObject.cs
@@ -8,23 +8,7 @@ namespace Microsoft.Diagnostics.DataContractReader.Contracts;
internal interface IObject : IContract
{
static string IContract.Name { get; } = nameof(Object);
- static IContract IContract.Create(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));
- return version switch
- {
- 1 => new Object_1(target, methodTableOffset, objectToMethodTableUnmask, stringMethodTable, syncTableEntries),
- _ => default(Object),
- };
- }
-
public virtual TargetPointer GetMethodTableAddress(TargetPointer address) => throw new NotImplementedException();
-
public virtual string GetStringValue(TargetPointer address) => throw new NotImplementedException();
public virtual TargetPointer GetArrayData(TargetPointer address, out uint count, out TargetPointer boundsStart, out TargetPointer lowerBounds) => throw new NotImplementedException();
public virtual bool GetBuiltInComData(TargetPointer address, out TargetPointer rcw, out TargetPointer ccw) => throw new NotImplementedException();
diff --git a/src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IRuntimeTypeSystem.cs
similarity index 93%
rename from src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IRuntimeTypeSystem.cs
index 67fd6db279604e..ddc2744d1d307b 100644
--- a/src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IRuntimeTypeSystem.cs
@@ -76,17 +76,6 @@ public enum ArrayFunctionType
internal interface IRuntimeTypeSystem : IContract
{
static string IContract.Name => nameof(RuntimeTypeSystem);
- static IContract IContract.Create(Target target, int version)
- {
- TargetPointer targetPointer = target.ReadGlobalPointer(Constants.Globals.FreeObjectMethodTable);
- TargetPointer freeObjectMethodTable = target.ReadPointer(targetPointer);
- ulong methodDescAlignment = target.ReadGlobal(Constants.Globals.MethodDescAlignment);
- return version switch
- {
- 1 => new RuntimeTypeSystem_1(target, freeObjectMethodTable, methodDescAlignment),
- _ => default(RuntimeTypeSystem),
- };
- }
#region TypeHandle inspection APIs
public virtual TypeHandle GetTypeHandle(TargetPointer address) => throw new NotImplementedException();
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IThread.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IThread.cs
new file mode 100644
index 00000000000000..cca1c522f10174
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IThread.cs
@@ -0,0 +1,56 @@
+// 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;
+
+internal record struct ThreadStoreData(
+ int ThreadCount,
+ TargetPointer FirstThread,
+ TargetPointer FinalizerThread,
+ TargetPointer GCThread);
+
+internal record struct ThreadStoreCounts(
+ int UnstartedThreadCount,
+ int BackgroundThreadCount,
+ int PendingThreadCount,
+ int DeadThreadCount);
+
+[Flags]
+internal enum ThreadState
+{
+ Unknown = 0x00000000,
+ Hijacked = 0x00000080, // Return address has been hijacked
+ Background = 0x00000200, // Thread is a background thread
+ Unstarted = 0x00000400, // Thread has never been started
+ Dead = 0x00000800, // Thread is dead
+ ThreadPoolWorker = 0x01000000, // Thread is a thread pool worker thread
+}
+
+internal record struct ThreadData(
+ uint Id,
+ TargetNUInt OSId,
+ ThreadState State,
+ bool PreemptiveGCDisabled,
+ TargetPointer AllocContextPointer,
+ TargetPointer AllocContextLimit,
+ TargetPointer Frame,
+ TargetPointer FirstNestedException,
+ TargetPointer TEB,
+ TargetPointer LastThrownObjectHandle,
+ TargetPointer NextThread);
+
+internal interface IThread : IContract
+{
+ static string IContract.Name { get; } = nameof(Thread);
+
+ public virtual ThreadStoreData GetThreadStoreData() => throw new NotImplementedException();
+ public virtual ThreadStoreCounts GetThreadCounts() => throw new NotImplementedException();
+ public virtual ThreadData GetThreadData(TargetPointer thread) => throw new NotImplementedException();
+}
+
+internal readonly struct Thread : IThread
+{
+ // Everything throws NotImplementedException
+}
diff --git a/src/native/managed/cdacreader/src/Data/IData.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Data/IData.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/IData.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Data/IData.cs
diff --git a/src/native/managed/cdacreader/src/DataType.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/DataType.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/DataType.cs
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/IContractFactory.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/IContractFactory.cs
new file mode 100644
index 00000000000000..4f1600ab0e7a73
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/IContractFactory.cs
@@ -0,0 +1,11 @@
+// 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;
+
+internal interface IContractFactory where TContract : Contracts.IContract
+{
+ TContract CreateContract(Target target, int version);
+}
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Microsoft.Diagnostics.DataContractReader.Abstractions.csproj b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Microsoft.Diagnostics.DataContractReader.Abstractions.csproj
new file mode 100644
index 00000000000000..142d604c464f84
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Microsoft.Diagnostics.DataContractReader.Abstractions.csproj
@@ -0,0 +1,21 @@
+
+
+
+ $(NetCoreAppToolCurrent)
+ Microsoft.Diagnostics.DataContractReader
+ enable
+ true
+
+ false
+ true
+ false
+
+
+
+
+
+
+
+
+
+
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs
new file mode 100644
index 00000000000000..46128d9dc59e0d
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/Target.cs
@@ -0,0 +1,186 @@
+// 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.Diagnostics.CodeAnalysis;
+using System.Numerics;
+
+namespace Microsoft.Diagnostics.DataContractReader;
+
+///
+/// Representation of the target under inspection
+///
+///
+/// This class provides APIs used by contracts for reading from the target and getting type and globals
+/// information. Like the contracts themselves in cdacreader, these are throwing APIs. Any callers at the boundaries
+/// (for example, unmanaged entry points, COM) should handle any exceptions.
+///
+internal abstract class Target
+{
+ ///
+ /// Pointer size of the target
+ ///
+ public abstract int PointerSize { get; }
+ ///
+ /// Endianness of the target
+ ///
+ public abstract bool IsLittleEndian { get; }
+
+ ///
+ /// Reads a well-known global pointer value from the target process
+ ///
+ /// The name of the global
+ /// The value of the global
+ public abstract TargetPointer ReadGlobalPointer(string global);
+
+ ///
+ /// Read a pointer from the target in target endianness
+ ///
+ /// Address to start reading from
+ /// Pointer read from the target}
+ public abstract TargetPointer ReadPointer(ulong address);
+
+ ///
+ /// Read some bytes from the target
+ ///
+ /// The address where to start reading
+ /// Destination to copy the bytes, the number of bytes to read is the span length
+ public abstract void ReadBuffer(ulong address, Span buffer);
+
+ ///
+ /// Read a null-terminated UTF-8 string from the target
+ ///
+ /// Address to start reading from
+ /// String read from the target}
+ public abstract string ReadUtf8String(ulong address);
+
+ ///
+ /// Read a null-terminated UTF-16 string from the target in target endianness
+ ///
+ /// Address to start reading from
+ /// String read from the target}
+ public abstract string ReadUtf16String(ulong address);
+
+ ///
+ /// Read a native unsigned integer from the target in target endianness
+ ///
+ /// Address to start reading from
+ /// Value read from the target
+ public abstract TargetNUInt ReadNUInt(ulong address);
+
+ ///
+ /// Read a well known global from the target process as a number in the target endianness
+ ///
+ /// The numeric type to be read
+ /// The name of the global
+ /// A numeric value
+ public abstract T ReadGlobal(string name) where T : struct, INumber;
+
+ ///
+ /// Read a value from the target in target endianness
+ ///
+ /// Type of value to read
+ /// Address to start reading from
+ /// Value read from the target
+ public abstract T Read(ulong address) where T : unmanaged, IBinaryInteger, IMinMaxValue;
+
+ ///
+ /// Read a target pointer from a span of bytes
+ ///
+ /// The span of bytes to read from
+ /// The target pointer read from the span
+ public abstract TargetPointer ReadPointerFromSpan(ReadOnlySpan bytes);
+
+
+ ///
+ /// Returns true if the given pointer is aligned to the pointer size of the target
+ ///
+ /// A target pointer value
+ ///
+ public abstract bool IsAlignedToPointerSize(TargetPointer pointer);
+
+ ///
+ /// Returns the information about the given well-known data type in the target process
+ ///
+ /// The name of the well known type
+ /// The information about the given type in the target process
+ public abstract TypeInfo GetTypeInfo(DataType type);
+
+ ///
+ /// Get the data cache for the target
+ ///
+ public abstract IDataCache ProcessedData { get; }
+
+ ///
+ /// Holds a snapshot of the target's structured data
+ ///
+ public interface IDataCache
+ {
+ ///
+ /// Read a value from the target and cache it, or return the currently cached value
+ ///
+ /// The type of data to be read
+ /// The address in the target where the data resides
+ /// The value that has been read from the target
+ T GetOrAdd(TargetPointer address) where T : Data.IData;
+ ///
+ /// Return the cached value for the given address, or null if no value is cached
+ ///
+ /// The type of the data to be read
+ /// The address in the target where the data resides
+ /// On return, set to the cached data value, or null if the data hasn't been cached yet.
+ /// True if a copy of the data is cached, or false otherwise
+ bool TryGet(ulong address, [NotNullWhen(true)] out T? data);
+ }
+
+ ///
+ /// Information about a well-known data type in the target process
+ ///
+ public readonly record struct TypeInfo
+ {
+ ///
+ /// The stride of the type in the target process.
+ /// This is a value that can be used to calculate the byte offset of an element in an array of this type.
+ ///
+ public uint? Size { get; init; }
+ ///
+ /// Information about the well-known fields of the type in the target process
+ ///
+ public readonly IReadOnlyDictionary Fields
+ {
+ get;
+ init;
+ }
+
+ public TypeInfo()
+ {
+ Fields = new Dictionary();
+ }
+ }
+
+ ///
+ /// Information about a well-known field of a well-known data type in the target process
+ ///
+ public readonly record struct FieldInfo
+ {
+ ///
+ /// The byte offset of the field in an instance of the type in the target process
+ ///
+ public int Offset {get; init; }
+ ///
+ /// The well known data type of the field in the target process
+ ///
+ public readonly DataType Type {get; init;}
+ ///
+ /// The name of the well known data type of the field in the target process, or null
+ /// if the target data descriptor did not record a name
+ ///
+ public readonly string? TypeName {get; init; }
+ }
+
+ ///
+ /// A cache of the contracts for the target process
+ ///
+ public abstract ContractRegistry Contracts { get; }
+}
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/TargetNUInt.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/TargetNUInt.cs
new file mode 100644
index 00000000000000..bbacb9a50b94fd
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/TargetNUInt.cs
@@ -0,0 +1,11 @@
+// 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;
+
+public readonly struct TargetNUInt
+{
+ public readonly ulong Value;
+ public TargetNUInt(ulong value) => Value = value;
+}
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/TargetPointer.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/TargetPointer.cs
new file mode 100644
index 00000000000000..9aef236554a38b
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/TargetPointer.cs
@@ -0,0 +1,26 @@
+// 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;
+
+public readonly struct TargetPointer : IEquatable
+{
+ public static TargetPointer Null = new(0);
+ public static TargetPointer Max32Bit = new(uint.MaxValue);
+ public static TargetPointer Max64Bit = new(ulong.MaxValue);
+
+ public readonly ulong Value;
+ public TargetPointer(ulong value) => Value = value;
+
+ public static implicit operator ulong(TargetPointer p) => p.Value;
+ public static implicit operator TargetPointer(ulong v) => new TargetPointer(v);
+
+ public static bool operator ==(TargetPointer left, TargetPointer right) => left.Value == right.Value;
+ public static bool operator !=(TargetPointer left, TargetPointer right) => left.Value != right.Value;
+
+ public override bool Equals(object? obj) => obj is TargetPointer pointer && Equals(pointer);
+ public bool Equals(TargetPointer other) => Value == other.Value;
+
+ public override int GetHashCode() => Value.GetHashCode();
+}
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/TargetSpan.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/TargetSpan.cs
new file mode 100644
index 00000000000000..8ecb093b49cb09
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Abstractions/TargetSpan.cs
@@ -0,0 +1,18 @@
+// 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;
+
+public readonly struct TargetSpan
+{
+ public TargetSpan(TargetPointer address, ulong size)
+ {
+ Address = address;
+ Size = size;
+ }
+
+ public TargetPointer Address { get; }
+ public ulong Size { get; }
+}
diff --git a/src/native/managed/cdacreader/src/Constants.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Constants.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Constants.cs
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreamsFactory.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreamsFactory.cs
new file mode 100644
index 00000000000000..e93fe712f00586
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreamsFactory.cs
@@ -0,0 +1,18 @@
+// 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;
+
+internal 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/cdacreader/src/Contracts/DacStreams_1.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreams_1.cs
similarity index 99%
rename from src/native/managed/cdacreader/src/Contracts/DacStreams_1.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreams_1.cs
index 688ec1d5b89844..0a6eb4d34de394 100644
--- a/src/native/managed/cdacreader/src/Contracts/DacStreams_1.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/DacStreams_1.cs
@@ -3,9 +3,7 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Text;
-using System.Threading.Tasks;
using Microsoft.Diagnostics.DataContractReader.Data;
namespace Microsoft.Diagnostics.DataContractReader.Contracts;
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadataFactory.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadataFactory.cs
new file mode 100644
index 00000000000000..029335787f3410
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadataFactory.cs
@@ -0,0 +1,19 @@
+// 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;
+
+internal 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/cdacreader/src/Contracts/EcmaMetadata_1.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadata_1.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Contracts/EcmaMetadata_1.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadata_1.cs
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExceptionFactory.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExceptionFactory.cs
new file mode 100644
index 00000000000000..209edd339d6a55
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ExceptionFactory.cs
@@ -0,0 +1,18 @@
+// 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;
+
+internal 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/cdacreader/src/Contracts/Exception_1.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Exception_1.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Contracts/Exception_1.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Exception_1.cs
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/LoaderFactory.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/LoaderFactory.cs
new file mode 100644
index 00000000000000..5c13186b4dce93
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/LoaderFactory.cs
@@ -0,0 +1,19 @@
+// 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;
+
+internal 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/cdacreader/src/Contracts/Loader_1.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Contracts/Loader_1.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Loader_1.cs
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ObjectFactory.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ObjectFactory.cs
new file mode 100644
index 00000000000000..4949a9f52fd729
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ObjectFactory.cs
@@ -0,0 +1,25 @@
+// 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;
+
+internal 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));
+ return version switch
+ {
+ 1 => new Object_1(target, methodTableOffset, objectToMethodTableUnmask, stringMethodTable, syncTableEntries),
+ _ => default(Object),
+ };
+ }
+
+}
diff --git a/src/native/managed/cdacreader/src/Contracts/Object_1.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Contracts/Object_1.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Object_1.cs
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystemFactory.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystemFactory.cs
new file mode 100644
index 00000000000000..8590f3e11a7cf8
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystemFactory.cs
@@ -0,0 +1,21 @@
+// 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;
+
+internal sealed class RuntimeTypeSystemFactory : IContractFactory
+{
+ IRuntimeTypeSystem IContractFactory.CreateContract(Target target, int version)
+ {
+ TargetPointer targetPointer = target.ReadGlobalPointer(Constants.Globals.FreeObjectMethodTable);
+ TargetPointer freeObjectMethodTable = target.ReadPointer(targetPointer);
+ ulong methodDescAlignment = target.ReadGlobal(Constants.Globals.MethodDescAlignment);
+ return version switch
+ {
+ 1 => new RuntimeTypeSystem_1(target, freeObjectMethodTable, methodDescAlignment),
+ _ => default(RuntimeTypeSystem),
+ };
+ }
+}
diff --git a/src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1.MethodTableFlags.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.MethodTableFlags.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1.MethodTableFlags.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.MethodTableFlags.cs
diff --git a/src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1.NonValidated.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.NonValidated.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1.NonValidated.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.NonValidated.cs
diff --git a/src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1.cs
diff --git a/src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1_Helpers.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1_Helpers.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Contracts/RuntimeTypeSystem_1_Helpers.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/RuntimeTypeSystem_1_Helpers.cs
diff --git a/src/native/managed/cdacreader/src/Contracts/Thread.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread.cs
similarity index 68%
rename from src/native/managed/cdacreader/src/Contracts/Thread.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread.cs
index 88308b23c1ee4e..312c300e5b74fa 100644
--- a/src/native/managed/cdacreader/src/Contracts/Thread.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/Thread.cs
@@ -5,46 +5,9 @@
namespace Microsoft.Diagnostics.DataContractReader.Contracts;
-internal record struct ThreadStoreData(
- int ThreadCount,
- TargetPointer FirstThread,
- TargetPointer FinalizerThread,
- TargetPointer GCThread);
-
-internal record struct ThreadStoreCounts(
- int UnstartedThreadCount,
- int BackgroundThreadCount,
- int PendingThreadCount,
- int DeadThreadCount);
-
-[Flags]
-internal enum ThreadState
-{
- Unknown = 0x00000000,
- Hijacked = 0x00000080, // Return address has been hijacked
- Background = 0x00000200, // Thread is a background thread
- Unstarted = 0x00000400, // Thread has never been started
- Dead = 0x00000800, // Thread is dead
- ThreadPoolWorker = 0x01000000, // Thread is a thread pool worker thread
-}
-
-internal record struct ThreadData(
- uint Id,
- TargetNUInt OSId,
- ThreadState State,
- bool PreemptiveGCDisabled,
- TargetPointer AllocContextPointer,
- TargetPointer AllocContextLimit,
- TargetPointer Frame,
- TargetPointer FirstNestedException,
- TargetPointer TEB,
- TargetPointer LastThrownObjectHandle,
- TargetPointer NextThread);
-
-internal interface IThread : IContract
+internal sealed class ThreadFactory : IContractFactory
{
- static string IContract.Name { get; } = nameof(Thread);
- static IContract IContract.Create(Target target, int version)
+ IThread IContractFactory.CreateContract(Target target, int version)
{
TargetPointer threadStorePointer = target.ReadGlobalPointer(Constants.Globals.ThreadStore);
TargetPointer threadStore = target.ReadPointer(threadStorePointer);
@@ -54,15 +17,6 @@ static IContract IContract.Create(Target target, int version)
_ => default(Thread),
};
}
-
- public virtual ThreadStoreData GetThreadStoreData() => throw new NotImplementedException();
- public virtual ThreadStoreCounts GetThreadCounts() => throw new NotImplementedException();
- public virtual ThreadData GetThreadData(TargetPointer thread) => throw new NotImplementedException();
-}
-
-internal readonly struct Thread : IThread
-{
- // Everything throws NotImplementedException
}
internal readonly struct Thread_1 : IThread
diff --git a/src/native/managed/cdacreader/src/Data/Array.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Array.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/Array.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Array.cs
diff --git a/src/native/managed/cdacreader/src/Data/DynamicMetadata.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/DynamicMetadata.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/DynamicMetadata.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/DynamicMetadata.cs
diff --git a/src/native/managed/cdacreader/src/Data/EEClass.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EEClass.cs
similarity index 95%
rename from src/native/managed/cdacreader/src/Data/EEClass.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EEClass.cs
index fd0ad35adbf9d6..c9e62eb39e85ef 100644
--- a/src/native/managed/cdacreader/src/Data/EEClass.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EEClass.cs
@@ -3,7 +3,7 @@
namespace Microsoft.Diagnostics.DataContractReader.Data;
-public sealed class EEClass : IData
+internal sealed class EEClass : IData
{
static EEClass IData.Create(Target target, TargetPointer address) => new EEClass(target, address);
public EEClass(Target target, TargetPointer address)
@@ -33,7 +33,7 @@ public EEClass(Target target, TargetPointer address)
public ushort NumNonVirtualSlots { get; init; }
}
-public sealed class ArrayClass : IData
+internal sealed class ArrayClass : IData
{
static ArrayClass IData.Create(Target target, TargetPointer address) => new ArrayClass(target, address);
public ArrayClass(Target target, TargetPointer address)
diff --git a/src/native/managed/cdacreader/src/Data/Exception.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Exception.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/Exception.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Exception.cs
diff --git a/src/native/managed/cdacreader/src/Data/ExceptionInfo.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ExceptionInfo.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/ExceptionInfo.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ExceptionInfo.cs
diff --git a/src/native/managed/cdacreader/src/Data/GCAllocContext.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/GCAllocContext.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/GCAllocContext.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/GCAllocContext.cs
diff --git a/src/native/managed/cdacreader/src/Data/GenericsDictInfo.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/GenericsDictInfo.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/GenericsDictInfo.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/GenericsDictInfo.cs
diff --git a/src/native/managed/cdacreader/src/Data/InteropSyncBlockInfo.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/InteropSyncBlockInfo.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/InteropSyncBlockInfo.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/InteropSyncBlockInfo.cs
diff --git a/src/native/managed/cdacreader/src/Data/MethodDesc.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodDesc.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/MethodDesc.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodDesc.cs
diff --git a/src/native/managed/cdacreader/src/Data/MethodDescChunk.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodDescChunk.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/MethodDescChunk.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodDescChunk.cs
diff --git a/src/native/managed/cdacreader/src/Data/MethodTable.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodTable.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/MethodTable.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodTable.cs
diff --git a/src/native/managed/cdacreader/src/Data/MethodTableAuxiliaryData.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodTableAuxiliaryData.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/MethodTableAuxiliaryData.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MethodTableAuxiliaryData.cs
diff --git a/src/native/managed/cdacreader/src/Data/Module.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Module.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/Module.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Module.cs
diff --git a/src/native/managed/cdacreader/src/Data/ModuleLookupMap.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ModuleLookupMap.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/ModuleLookupMap.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ModuleLookupMap.cs
diff --git a/src/native/managed/cdacreader/src/Data/ObjectHandle.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ObjectHandle.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/ObjectHandle.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ObjectHandle.cs
diff --git a/src/native/managed/cdacreader/src/Data/RuntimeThreadLocals.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/RuntimeThreadLocals.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/RuntimeThreadLocals.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/RuntimeThreadLocals.cs
diff --git a/src/native/managed/cdacreader/src/Data/String.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/String.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/String.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/String.cs
diff --git a/src/native/managed/cdacreader/src/Data/SyncBlock.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/SyncBlock.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/SyncBlock.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/SyncBlock.cs
diff --git a/src/native/managed/cdacreader/src/Data/SyncTableEntry.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/SyncTableEntry.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/SyncTableEntry.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/SyncTableEntry.cs
diff --git a/src/native/managed/cdacreader/src/Data/Thread.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Thread.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/Thread.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Thread.cs
diff --git a/src/native/managed/cdacreader/src/Data/ThreadStore.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ThreadStore.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/ThreadStore.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ThreadStore.cs
diff --git a/src/native/managed/cdacreader/src/Data/TypeDesc.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/TypeDesc.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Data/TypeDesc.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Data/TypeDesc.cs
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Microsoft.Diagnostics.DataContractReader.Contracts.csproj b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Microsoft.Diagnostics.DataContractReader.Contracts.csproj
new file mode 100644
index 00000000000000..70748b48d2bc35
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader.Contracts/Microsoft.Diagnostics.DataContractReader.Contracts.csproj
@@ -0,0 +1,24 @@
+
+
+
+ $(NetCoreAppToolCurrent)
+ Microsoft.Diagnostics.DataContractReader
+ enable
+ true
+
+ false
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs
new file mode 100644
index 00000000000000..0ff37597326214
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/CachingContractRegistry.cs
@@ -0,0 +1,65 @@
+// 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 Microsoft.Diagnostics.DataContractReader.Contracts;
+
+namespace Microsoft.Diagnostics.DataContractReader;
+
+///
+/// Contract registry that caches contracts for a target
+///
+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 Target _target;
+ private readonly TryGetContractVersionDelegate _tryGetContractVersion;
+
+ public CachingContractRegistry(Target target, TryGetContractVersionDelegate tryGetContractVersion, Action>>? configureFactories = null)
+ {
+ _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(),
+ };
+ configureFactories?.Invoke(_factories);
+ }
+
+ public override IException Exception => GetContract();
+ public override ILoader Loader => GetContract();
+ public override IEcmaMetadata EcmaMetadata => GetContract();
+ public override IObject Object => GetContract();
+ public override IThread Thread => GetContract();
+ public override IRuntimeTypeSystem RuntimeTypeSystem => GetContract();
+ public override IDacStreams DacStreams => GetContract();
+
+ private TContract GetContract() where TContract : IContract
+ {
+ if (_contracts.TryGetValue(typeof(TContract), out IContract? contractMaybe))
+ return (TContract)contractMaybe;
+
+ if (!_tryGetContractVersion(TContract.Name, out int version))
+ throw new NotImplementedException();
+
+ if (!_factories.TryGetValue(typeof(TContract), out IContractFactory? factory))
+ throw new NotImplementedException();
+ // Create and register the contract
+ TContract contract = (TContract)factory.CreateContract(_target, version);
+ 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/cdacreader/src/ContractDescriptorParser.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorParser.cs
similarity index 99%
rename from src/native/managed/cdacreader/src/ContractDescriptorParser.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorParser.cs
index a82235731e4a07..9d351328daafe2 100644
--- a/src/native/managed/cdacreader/src/ContractDescriptorParser.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorParser.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
-using System.Diagnostics.Contracts;
using System.Text.Json;
using System.Text.Json.Serialization;
diff --git a/src/native/managed/cdacreader/src/Target.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs
similarity index 82%
rename from src/native/managed/cdacreader/src/Target.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs
index afa989a66f4b00..3c3b4c67118393 100644
--- a/src/native/managed/cdacreader/src/Target.cs
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs
@@ -12,45 +12,6 @@
namespace Microsoft.Diagnostics.DataContractReader;
-public readonly struct TargetPointer : IEquatable
-{
- public static TargetPointer Null = new(0);
- public static TargetPointer Max32Bit = new(uint.MaxValue);
- public static TargetPointer Max64Bit = new(ulong.MaxValue);
-
- public readonly ulong Value;
- public TargetPointer(ulong value) => Value = value;
-
- public static implicit operator ulong(TargetPointer p) => p.Value;
- public static implicit operator TargetPointer(ulong v) => new TargetPointer(v);
-
- public static bool operator ==(TargetPointer left, TargetPointer right) => left.Value == right.Value;
- public static bool operator !=(TargetPointer left, TargetPointer right) => left.Value != right.Value;
-
- public override bool Equals(object? obj) => obj is TargetPointer pointer && Equals(pointer);
- public bool Equals(TargetPointer other) => Value == other.Value;
-
- public override int GetHashCode() => Value.GetHashCode();
-}
-
-public readonly struct TargetNUInt
-{
- public readonly ulong Value;
- public TargetNUInt(ulong value) => Value = value;
-}
-
-public readonly struct TargetSpan
-{
- public TargetSpan(TargetPointer address, ulong size)
- {
- Address = address;
- Size = size;
- }
-
- public TargetPointer Address { get; }
- public ulong Size { get; }
-}
-
///
/// Representation of the target under inspection
///
@@ -60,23 +21,8 @@ public TargetSpan(TargetPointer address, ulong size)
/// these are throwing APIs. Any callers at the boundaries (for example, unmanaged entry points, COM)
/// should handle any exceptions.
///
-public sealed unsafe class Target
+internal sealed unsafe class ContractDescriptorTarget : Target
{
- public record struct TypeInfo
- {
- public uint? Size;
- public Dictionary Fields = [];
-
- public TypeInfo() { }
- }
-
- public record struct FieldInfo
- {
- public int Offset;
- public DataType Type;
- public string? TypeName;
- }
-
private const int StackAllocByteThreshold = 1024;
private readonly struct Configuration
@@ -90,20 +36,20 @@ private readonly struct Configuration
private readonly Dictionary _contracts = [];
private readonly IReadOnlyDictionary _globals = new Dictionary();
- private readonly Dictionary _knownTypes = [];
- private readonly Dictionary _types = [];
+ private readonly Dictionary _knownTypes = [];
+ private readonly Dictionary _types = [];
- internal Contracts.Registry Contracts { get; }
- internal DataCache ProcessedData { get; }
+ public override ContractRegistry Contracts { get; }
+ public override DataCache ProcessedData { get; }
public delegate int ReadFromTargetDelegate(ulong address, Span bufferToFill);
- public static bool TryCreate(ulong contractDescriptor, ReadFromTargetDelegate readFromTarget, out Target? target)
+ public static bool TryCreate(ulong contractDescriptor, ReadFromTargetDelegate readFromTarget, out ContractDescriptorTarget? target)
{
Reader reader = new Reader(readFromTarget);
if (TryReadContractDescriptor(contractDescriptor, reader, out Configuration config, out ContractDescriptorParser.ContractDescriptor? descriptor, out TargetPointer[] pointerData))
{
- target = new Target(config, descriptor!, pointerData, reader);
+ target = new ContractDescriptorTarget(config, descriptor!, pointerData, reader);
return true;
}
@@ -111,9 +57,9 @@ public static bool TryCreate(ulong contractDescriptor, ReadFromTargetDelegate re
return false;
}
- private Target(Configuration config, ContractDescriptorParser.ContractDescriptor descriptor, TargetPointer[] pointerData, Reader reader)
+ private ContractDescriptorTarget(Configuration config, ContractDescriptorParser.ContractDescriptor descriptor, TargetPointer[] pointerData, Reader reader)
{
- Contracts = new Contracts.Registry(this);
+ Contracts = new CachingContractRegistry(this, this.TryGetContractVersion);
ProcessedData = new DataCache(this);
_config = config;
_reader = reader;
@@ -125,12 +71,12 @@ private Target(Configuration config, ContractDescriptorParser.ContractDescriptor
{
foreach ((string name, ContractDescriptorParser.TypeDescriptor type) in descriptor.Types)
{
- TypeInfo typeInfo = new() { Size = type.Size };
+ Dictionary fieldInfos = [];
if (type.Fields is not null)
{
foreach ((string fieldName, ContractDescriptorParser.FieldDescriptor field) in type.Fields)
{
- typeInfo.Fields[fieldName] = new FieldInfo()
+ fieldInfos[fieldName] = new Target.FieldInfo()
{
Offset = field.Offset,
Type = field.Type is null ? DataType.Unknown : GetDataType(field.Type),
@@ -138,6 +84,7 @@ private Target(Configuration config, ContractDescriptorParser.ContractDescriptor
};
}
}
+ Target.TypeInfo typeInfo = new() { Size = type.Size, Fields = fieldInfos };
DataType dataType = GetDataType(name);
if (dataType is not DataType.Unknown)
@@ -263,7 +210,8 @@ private static DataType GetDataType(string type)
return DataType.Unknown;
}
- public int PointerSize => _config.PointerSize;
+ public override int PointerSize => _config.PointerSize;
+ public override bool IsLittleEndian => _config.IsLittleEndian;
///
/// Read a value from the target in target endianness
@@ -271,7 +219,7 @@ private static DataType GetDataType(string type)
/// Type of value to read
/// Address to start reading from
/// Value read from the target
- public T Read(ulong address) where T : unmanaged, IBinaryInteger, IMinMaxValue
+ public override T Read(ulong address)
{
if (!TryRead(address, _config.IsLittleEndian, _reader, out T value))
throw new InvalidOperationException($"Failed to read {typeof(T)} at 0x{address:x8}.");
@@ -308,7 +256,7 @@ private static T Read(ReadOnlySpan bytes, bool isLittleEndian) where T
return value;
}
- public void ReadBuffer(ulong address, Span buffer)
+ public override void ReadBuffer(ulong address, Span buffer)
{
if (!TryReadBuffer(address, buffer))
throw new InvalidOperationException($"Failed to read {buffer.Length} bytes at 0x{address:x8}.");
@@ -330,7 +278,7 @@ private static bool IsSigned() where T : struct, INumberBase, IMinMaxValue
///
/// Address to start reading from
/// Pointer read from the target}
- public TargetPointer ReadPointer(ulong address)
+ public override TargetPointer ReadPointer(ulong address)
{
if (!TryReadPointer(address, _config, _reader, out TargetPointer pointer))
throw new InvalidOperationException($"Failed to read pointer at 0x{address:x8}.");
@@ -338,7 +286,7 @@ public TargetPointer ReadPointer(ulong address)
return pointer;
}
- public TargetPointer ReadPointerFromSpan(ReadOnlySpan bytes)
+ public override TargetPointer ReadPointerFromSpan(ReadOnlySpan bytes)
{
if (_config.PointerSize == sizeof(uint))
{
@@ -368,7 +316,7 @@ public void ReadPointers(ulong address, Span buffer)
///
/// Address to start reading from
/// String read from the target}
- public string ReadUtf8String(ulong address)
+ public override string ReadUtf8String(ulong address)
{
// Read characters until we find the null terminator
ulong end = address;
@@ -393,7 +341,7 @@ public string ReadUtf8String(ulong address)
///
/// Address to start reading from
/// String read from the target}
- public string ReadUtf16String(ulong address)
+ public override string ReadUtf16String(ulong address)
{
// Read characters until we find the null terminator
ulong end = address;
@@ -421,7 +369,7 @@ public string ReadUtf16String(ulong address)
///
/// Address to start reading from
/// Value read from the target
- public TargetNUInt ReadNUInt(ulong address)
+ public override TargetNUInt ReadNUInt(ulong address)
{
if (!TryReadNUInt(address, _config, _reader, out ulong value))
throw new InvalidOperationException($"Failed to read nuint at 0x{address:x8}.");
@@ -465,12 +413,10 @@ public bool IsAlignedToPointerSize(uint value)
=> IsAligned(value, _config.PointerSize);
public bool IsAlignedToPointerSize(ulong value)
=> IsAligned(value, _config.PointerSize);
- public bool IsAlignedToPointerSize(TargetPointer pointer)
+ public override bool IsAlignedToPointerSize(TargetPointer pointer)
=> IsAligned(pointer.Value, _config.PointerSize);
- public char DirectorySeparator => (char)ReadGlobal(Constants.Globals.DirectorySeparator);
-
- public T ReadGlobal(string name) where T : struct, INumber
+ public override T ReadGlobal(string name)
=> ReadGlobal(name, out _);
public T ReadGlobal(string name, out string? type) where T : struct, INumber
@@ -482,7 +428,7 @@ public T ReadGlobal(string name, out string? type) where T : struct, INumber<
return T.CreateChecked(global.Value);
}
- public TargetPointer ReadGlobalPointer(string name)
+ public override TargetPointer ReadGlobalPointer(string name)
=> ReadGlobalPointer(name, out _);
public TargetPointer ReadGlobalPointer(string name, out string? type)
@@ -494,17 +440,17 @@ public TargetPointer ReadGlobalPointer(string name, out string? type)
return new TargetPointer(global.Value);
}
- public TypeInfo GetTypeInfo(DataType type)
+ public override TypeInfo GetTypeInfo(DataType type)
{
- if (!_knownTypes.TryGetValue(type, out TypeInfo typeInfo))
+ if (!_knownTypes.TryGetValue(type, out Target.TypeInfo typeInfo))
throw new InvalidOperationException($"Failed to get type info for '{type}'");
return typeInfo;
}
- public TypeInfo GetTypeInfo(string type)
+ public Target.TypeInfo GetTypeInfo(string type)
{
- if (_types.TryGetValue(type, out TypeInfo typeInfo))
+ if (_types.TryGetValue(type, out Target.TypeInfo typeInfo))
return typeInfo;
DataType dataType = GetDataType(type);
@@ -521,12 +467,12 @@ internal bool TryGetContractVersion(string contractName, out int version)
/// Store of addresses that have already been read into corresponding data models.
/// This is simply used to avoid re-processing data on every request.
///
- internal sealed class DataCache
+ internal sealed class DataCache : Target.IDataCache
{
- private readonly Target _target;
+ private readonly ContractDescriptorTarget _target;
private readonly Dictionary<(ulong, Type), object?> _readDataByAddress = [];
- public DataCache(Target target)
+ public DataCache(ContractDescriptorTarget target)
{
_target = target;
}
diff --git a/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/Microsoft.Diagnostics.DataContractReader.csproj b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/Microsoft.Diagnostics.DataContractReader.csproj
new file mode 100644
index 00000000000000..b0868e188bb61a
--- /dev/null
+++ b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/Microsoft.Diagnostics.DataContractReader.csproj
@@ -0,0 +1,27 @@
+
+
+
+ $(NetCoreAppToolCurrent)
+ Microsoft.Diagnostics.DataContractReader
+ enable
+ true
+
+ false
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/native/managed/cdacreader/src/Root.cs b/src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/Root.cs
similarity index 100%
rename from src/native/managed/cdacreader/src/Root.cs
rename to src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/Root.cs
diff --git a/src/native/managed/cdacreader/src/Contracts/Registry.cs b/src/native/managed/cdacreader/src/Contracts/Registry.cs
deleted file mode 100644
index a5d3721f06f885..00000000000000
--- a/src/native/managed/cdacreader/src/Contracts/Registry.cs
+++ /dev/null
@@ -1,45 +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;
-
-internal sealed class Registry
-{
- // Contracts that have already been created for a target.
- // Items should not be removed from this, only added.
- private readonly Dictionary _contracts = [];
- private readonly Target _target;
-
- public Registry(Target target)
- {
- _target = target;
- }
-
- public IException Exception => GetContract();
- public ILoader Loader => GetContract();
- public IEcmaMetadata EcmaMetadata => GetContract();
- public IObject Object => GetContract();
- public IThread Thread => GetContract();
- public IRuntimeTypeSystem RuntimeTypeSystem => GetContract();
- public IDacStreams DacStreams => GetContract();
-
- private T GetContract() where T : IContract
- {
- if (_contracts.TryGetValue(typeof(T), out IContract? contractMaybe))
- return (T)contractMaybe;
-
- if (!_target.TryGetContractVersion(T.Name, out int version))
- throw new NotImplementedException();
-
- // Create and register the contract
- IContract contract = T.Create(_target, version);
- if (_contracts.TryAdd(typeof(T), contract))
- return (T)contract;
-
- // Contract was already registered by someone else
- return (T)_contracts[typeof(T)];
- }
-}
diff --git a/src/native/managed/cdacreader/src/Entrypoints.cs b/src/native/managed/cdacreader/src/Entrypoints.cs
index d58f4750099522..17983bb68ed205 100644
--- a/src/native/managed/cdacreader/src/Entrypoints.cs
+++ b/src/native/managed/cdacreader/src/Entrypoints.cs
@@ -15,13 +15,13 @@ internal static class Entrypoints
private static unsafe int Init(ulong descriptor, delegate* unmanaged readFromTarget, void* readContext, IntPtr* handle)
{
// TODO: [cdac] Better error code/details
- if (!Target.TryCreate(descriptor, (address, buffer) =>
+ if (!ContractDescriptorTarget.TryCreate(descriptor, (address, buffer) =>
{
fixed (byte* bufferPtr = buffer)
{
return readFromTarget(address, bufferPtr, (uint)buffer.Length, readContext);
}
- }, out Target? target))
+ }, out ContractDescriptorTarget? target))
return -1;
GCHandle gcHandle = GCHandle.Alloc(target);
diff --git a/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.cs b/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.cs
index 37e513995767b6..8f4a13500429e0 100644
--- a/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.cs
+++ b/src/native/managed/cdacreader/src/Legacy/SOSDacImpl.cs
@@ -3,9 +3,6 @@
using Microsoft.Diagnostics.DataContractReader.Contracts;
using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using System.Text;
@@ -159,7 +156,9 @@ public unsafe int GetMethodDescName(ulong methodDesc, uint count, char* name, ui
Contracts.ModuleHandle module = _target.Contracts.Loader.GetModuleHandle(modulePtr);
string modulePath = _target.Contracts.Loader.GetPath(module);
ReadOnlySpan moduleSpan = modulePath.AsSpan();
- int pathNameSpanIndex = moduleSpan.LastIndexOf(_target.DirectorySeparator);
+ char directorySeparator = (char)_target.ReadGlobal(Constants.Globals.DirectorySeparator);
+
+ int pathNameSpanIndex = moduleSpan.LastIndexOf(directorySeparator);
if (pathNameSpanIndex != -1)
{
moduleSpan = moduleSpan.Slice(pathNameSpanIndex + 1);
diff --git a/src/native/managed/cdacreader/src/Legacy/SigFormat.cs b/src/native/managed/cdacreader/src/Legacy/SigFormat.cs
index f2928393eed400..69246f6b1e85f0 100644
--- a/src/native/managed/cdacreader/src/Legacy/SigFormat.cs
+++ b/src/native/managed/cdacreader/src/Legacy/SigFormat.cs
@@ -2,14 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
using Microsoft.Diagnostics.DataContractReader.Contracts;
namespace Microsoft.Diagnostics.DataContractReader.Legacy
diff --git a/src/native/managed/cdacreader/src/cdacreader.csproj b/src/native/managed/cdacreader/src/cdacreader.csproj
index 1c973cac51a571..a8fd13e4992348 100644
--- a/src/native/managed/cdacreader/src/cdacreader.csproj
+++ b/src/native/managed/cdacreader/src/cdacreader.csproj
@@ -12,9 +12,6 @@
false
-
-
-
@@ -24,4 +21,8 @@
+
+
+
+
diff --git a/src/native/managed/cdacreader/tests/ContractDescriptorParserTests.cs b/src/native/managed/cdacreader/tests/ContractDescriptorParserTests.cs
index 6f93b1225670e4..04b750dd6063b7 100644
--- a/src/native/managed/cdacreader/tests/ContractDescriptorParserTests.cs
+++ b/src/native/managed/cdacreader/tests/ContractDescriptorParserTests.cs
@@ -3,7 +3,6 @@
using System;
using System.Text.Json;
-using System.Text.Unicode;
using Xunit;
namespace Microsoft.Diagnostics.DataContractReader.UnitTests;
diff --git a/src/native/managed/cdacreader/tests/DacStreamsTests.cs b/src/native/managed/cdacreader/tests/DacStreamsTests.cs
index b3fbcae943f7a0..83eef79181a460 100644
--- a/src/native/managed/cdacreader/tests/DacStreamsTests.cs
+++ b/src/native/managed/cdacreader/tests/DacStreamsTests.cs
@@ -47,7 +47,7 @@ private static unsafe void DacStreamsContractHelper(MockTarget.Architecture arch
builder = configure(builder);
}
- bool success = builder.TryCreateTarget(out Target? target);
+ bool success = builder.TryCreateTarget(out ContractDescriptorTarget? target);
Assert.True(success);
testCase(target);
diff --git a/src/native/managed/cdacreader/tests/MethodTableTests.cs b/src/native/managed/cdacreader/tests/MethodTableTests.cs
index 822e1d6a26af70..d86c2dd2e8eb2f 100644
--- a/src/native/managed/cdacreader/tests/MethodTableTests.cs
+++ b/src/native/managed/cdacreader/tests/MethodTableTests.cs
@@ -32,7 +32,7 @@ private static void RTSContractHelper(MockTarget.Architecture arch, ConfigureCon
builder = configure(builder);
}
- bool success = builder.TryCreateTarget(out Target? target);
+ bool success = builder.TryCreateTarget(out ContractDescriptorTarget? target);
Assert.True(success);
testCase(target);
diff --git a/src/native/managed/cdacreader/tests/MockDescriptors.cs b/src/native/managed/cdacreader/tests/MockDescriptors.cs
index 3a173813714841..8ffcd23556afdd 100644
--- a/src/native/managed/cdacreader/tests/MockDescriptors.cs
+++ b/src/native/managed/cdacreader/tests/MockDescriptors.cs
@@ -13,7 +13,7 @@ public class MockDescriptors
{
private static readonly Target.TypeInfo MethodTableTypeInfo = new()
{
- Fields = {
+ Fields = new Dictionary {
{ nameof(Data.MethodTable.MTFlags), new() { Offset = 4, Type = DataType.uint32}},
{ nameof(Data.MethodTable.BaseSize), new() { Offset = 8, Type = DataType.uint32}},
{ nameof(Data.MethodTable.MTFlags2), new() { Offset = 12, Type = DataType.uint32}},
@@ -28,7 +28,7 @@ public class MockDescriptors
private static readonly Target.TypeInfo EEClassTypeInfo = new Target.TypeInfo()
{
- Fields = {
+ Fields = new Dictionary {
{ nameof (Data.EEClass.MethodTable), new () { Offset = 8, Type = DataType.pointer}},
{ nameof (Data.EEClass.CorTypeAttr), new () { Offset = 16, Type = DataType.uint32}},
{ nameof (Data.EEClass.NumMethods), new () { Offset = 20, Type = DataType.uint16}},
@@ -39,21 +39,21 @@ public class MockDescriptors
private static readonly Target.TypeInfo ArrayClassTypeInfo = new Target.TypeInfo()
{
- Fields = {
+ Fields = new Dictionary {
{ nameof (Data.ArrayClass.Rank), new () { Offset = 0x70, Type = DataType.uint8}},
}
};
private static readonly Target.TypeInfo ObjectTypeInfo = new()
{
- Fields = {
+ Fields = new Dictionary {
{ "m_pMethTab", new() { Offset = 0, Type = DataType.pointer} },
}
};
private static readonly Target.TypeInfo StringTypeInfo = new Target.TypeInfo()
{
- Fields = {
+ Fields = new Dictionary {
{ "m_StringLength", new() { Offset = 0x8, Type = DataType.uint32} },
{ "m_FirstChar", new() { Offset = 0xc, Type = DataType.uint16} },
}
@@ -61,28 +61,28 @@ public class MockDescriptors
private static readonly Target.TypeInfo ArrayTypeInfo = new Target.TypeInfo()
{
- Fields = {
+ Fields = new Dictionary {
{ "m_NumComponents", new() { Offset = 0x8, Type = DataType.uint32} },
},
};
private static readonly Target.TypeInfo SyncTableEntryInfo = new Target.TypeInfo()
{
- Fields = {
+ Fields = new Dictionary {
{ nameof(Data.SyncTableEntry.SyncBlock), new() { Offset = 0, Type = DataType.pointer} },
},
};
private static readonly Target.TypeInfo SyncBlockTypeInfo = new Target.TypeInfo()
{
- Fields = {
+ Fields = new Dictionary {
{ nameof(Data.SyncBlock.InteropInfo), new() { Offset = 0, Type = DataType.pointer} },
},
};
private static readonly Target.TypeInfo InteropSyncBlockTypeInfo = new Target.TypeInfo()
{
- Fields = {
+ Fields = new Dictionary {
{ nameof(Data.InteropSyncBlockInfo.RCW), new() { Offset = 0, Type = DataType.pointer} },
{ nameof(Data.InteropSyncBlockInfo.CCW), new() { Offset = 0x8, Type = DataType.pointer} },
},
diff --git a/src/native/managed/cdacreader/tests/MockMemorySpace.cs b/src/native/managed/cdacreader/tests/MockMemorySpace.cs
index 0aa007a7791a9e..645d251dbbea99 100644
--- a/src/native/managed/cdacreader/tests/MockMemorySpace.cs
+++ b/src/native/managed/cdacreader/tests/MockMemorySpace.cs
@@ -226,10 +226,10 @@ private bool FragmentFits(HeapFragment f)
return true;
}
- public bool TryCreateTarget([NotNullWhen(true)] out Target? target)
+ public bool TryCreateTarget([NotNullWhen(true)] out ContractDescriptorTarget? target)
{
ReadContext context = CreateContext();
- return Target.TryCreate(context.ContractDescriptor.Address, context.ReadFromTarget, out target);
+ return ContractDescriptorTarget.TryCreate(context.ContractDescriptor.Address, context.ReadFromTarget, out target);
}
}
diff --git a/src/native/managed/cdacreader/tests/ObjectTests.cs b/src/native/managed/cdacreader/tests/ObjectTests.cs
index 4f39edf44b9f1d..8a3c05dd79ea15 100644
--- a/src/native/managed/cdacreader/tests/ObjectTests.cs
+++ b/src/native/managed/cdacreader/tests/ObjectTests.cs
@@ -30,7 +30,7 @@ private static void ObjectContractHelper(MockTarget.Architecture arch, Configure
builder = configure(builder);
}
- bool success = builder.TryCreateTarget(out Target? target);
+ bool success = builder.TryCreateTarget(out ContractDescriptorTarget? target);
Assert.True(success);
testCase(target);
}
diff --git a/src/native/managed/cdacreader/tests/TargetTests.cs b/src/native/managed/cdacreader/tests/TargetTests.cs
index 1ce64afceca0d2..50638e1f8c817e 100644
--- a/src/native/managed/cdacreader/tests/TargetTests.cs
+++ b/src/native/managed/cdacreader/tests/TargetTests.cs
@@ -17,14 +17,14 @@ public unsafe class TargetTests
// Size and fields
[DataType.Thread] = new(){
Size = 56,
- Fields = {
+ Fields = new Dictionary {
{ "Field1", new(){ Offset = 8, Type = DataType.uint16, TypeName = DataType.uint16.ToString() }},
{ "Field2", new(){ Offset = 16, Type = DataType.GCHandle, TypeName = DataType.GCHandle.ToString() }},
{ "Field3", new(){ Offset = 32 }}
}},
// Fields only
[DataType.ThreadStore] = new(){
- Fields = {
+ Fields = new Dictionary {
{ "Field1", new(){ Offset = 0, TypeName = "FieldType" }},
{ "Field2", new(){ Offset = 8 }}
}},
@@ -44,7 +44,7 @@ public void GetTypeInfo(MockTarget.Architecture arch)
.SetGlobals(Array.Empty<(string, ulong, string?)>())
.SetContracts(Array.Empty());
- bool success = builder.TryCreateTarget(out Target? target);
+ bool success = builder.TryCreateTarget(out ContractDescriptorTarget? target);
Assert.True(success);
foreach ((DataType type, Target.TypeInfo info) in TestTypes)
@@ -90,7 +90,7 @@ public void ReadGlobalValue(MockTarget.Architecture arch)
.SetGlobals(TestGlobals)
.SetContracts([]);
- bool success = builder.TryCreateTarget(out Target? target);
+ bool success = builder.TryCreateTarget(out ContractDescriptorTarget? target);
Assert.True(success);
ValidateGlobals(target, TestGlobals);
@@ -107,7 +107,7 @@ public void ReadIndirectGlobalValue(MockTarget.Architecture arch)
.SetGlobals(TestGlobals.Select(MakeGlobalToIndirect).ToArray(),
TestGlobals.Select((g) => g.Value).ToArray());
- bool success = builder.TryCreateTarget(out Target? target);
+ bool success = builder.TryCreateTarget(out ContractDescriptorTarget? target);
Assert.True(success);
// Indirect values are pointer-sized, so max 32-bits for a 32-bit target
@@ -124,7 +124,7 @@ public void ReadIndirectGlobalValue(MockTarget.Architecture arch)
}
private static void ValidateGlobals(
- Target target,
+ ContractDescriptorTarget target,
(string Name, ulong Value, string? Type)[] globals,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = "",
diff --git a/src/native/managed/compile-native.proj b/src/native/managed/compile-native.proj
index bcda8c5d6b57b5..dea5d2c6380da5 100644
--- a/src/native/managed/compile-native.proj
+++ b/src/native/managed/compile-native.proj
@@ -50,7 +50,7 @@