Skip to content

Commit e43ba03

Browse files
author
Max Charlamb
committed
adds DAC like entrypoint, Platform descriptor WIP
1 parent 74158bc commit e43ba03

File tree

3 files changed

+104
-23
lines changed

3 files changed

+104
-23
lines changed

src/native/managed/cdacreader/Microsoft.Diagnostics.DataContractReader/ContractDescriptorTarget.cs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,22 @@ private readonly struct Configuration
4444

4545
public delegate int ReadFromTargetDelegate(ulong address, Span<byte> bufferToFill);
4646
public delegate int GetTargetThreadContextDelegate(uint threadId, uint contextFlags, uint contextSize, Span<byte> bufferToFill);
47-
public delegate int GetTargetPlatformDelegate(out int platform);
4847

4948
/// <summary>
5049
/// Create a new target instance from a contract descriptor embedded in the target memory.
5150
/// </summary>
5251
/// <param name="contractDescriptor">The offset of the contract descriptor in the target memory</param>
5352
/// <param name="readFromTarget">A callback to read memory blocks at a given address from the target</param>
5453
/// <param name="getThreadContext">A callback to fetch a thread's context</param>
55-
/// <param name="getTargetPlatform">A callback to fetch the target's platform</param>
5654
/// <param name="target">The target object.</param>
5755
/// <returns>If a target instance could be created, <c>true</c>; otherwise, <c>false</c>.</returns>
5856
public static bool TryCreate(
5957
ulong contractDescriptor,
6058
ReadFromTargetDelegate readFromTarget,
6159
GetTargetThreadContextDelegate getThreadContext,
62-
GetTargetPlatformDelegate getTargetPlatform,
63-
out ContractDescriptorTarget? target)
60+
[NotNullWhen(true)] out ContractDescriptorTarget? target)
6461
{
65-
Reader reader = new Reader(readFromTarget, getThreadContext, getTargetPlatform);
62+
Reader reader = new Reader(readFromTarget, getThreadContext);
6663
if (TryReadContractDescriptor(
6764
contractDescriptor,
6865
reader,
@@ -94,15 +91,14 @@ public static ContractDescriptorTarget Create(
9491
TargetPointer[] globalPointerValues,
9592
ReadFromTargetDelegate readFromTarget,
9693
GetTargetThreadContextDelegate getThreadContext,
97-
GetTargetPlatformDelegate getTargetPlatform,
9894
bool isLittleEndian,
9995
int pointerSize)
10096
{
10197
return new ContractDescriptorTarget(
10298
new Configuration { IsLittleEndian = isLittleEndian, PointerSize = pointerSize },
10399
contractDescriptor,
104100
globalPointerValues,
105-
new Reader(readFromTarget, getThreadContext, getTargetPlatform));
101+
new Reader(readFromTarget, getThreadContext));
106102
}
107103

108104
private ContractDescriptorTarget(Configuration config, ContractDescriptorParser.ContractDescriptor descriptor, TargetPointer[] pointerData, Reader reader)
@@ -267,8 +263,7 @@ public override CorDebugPlatform Platform
267263
{
268264
get
269265
{
270-
_reader.GetTargetPlatform(out int platform);
271-
return (CorDebugPlatform)platform;
266+
return CorDebugPlatform.CORDB_PLATFORM_WINDOWS_AMD64;
272267
}
273268
}
274269

@@ -594,8 +589,7 @@ public void Clear()
594589

595590
private readonly struct Reader(
596591
ReadFromTargetDelegate readFromTarget,
597-
GetTargetThreadContextDelegate getThreadContext,
598-
GetTargetPlatformDelegate getTargetPlatform)
592+
GetTargetThreadContextDelegate getThreadContext)
599593
{
600594
public int ReadFromTarget(ulong address, Span<byte> buffer)
601595
{
@@ -605,11 +599,6 @@ public int ReadFromTarget(ulong address, Span<byte> buffer)
605599
public int ReadFromTarget(ulong address, byte* buffer, uint bytesToRead)
606600
=> readFromTarget(address, new Span<byte>(buffer, checked((int)bytesToRead)));
607601

608-
public int GetTargetPlatform(out int platform)
609-
{
610-
return getTargetPlatform(out platform);
611-
}
612-
613602
public int GetThreadContext(uint threadId, uint contextFlags, uint contextSize, Span<byte> buffer)
614603
{
615604
return getThreadContext(threadId, contextFlags, contextSize, buffer);

src/native/managed/cdacreader/src/Entrypoints.cs

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Runtime.InteropServices;
66
using System.Runtime.InteropServices.Marshalling;
7+
using Microsoft.Diagnostics.DataContractReader.Legacy;
78

89
namespace Microsoft.Diagnostics.DataContractReader;
910

@@ -37,13 +38,6 @@ private static unsafe int Init(
3738
return readThreadContext(threadId, contextFlags, contextSize, bufferPtr, readContext);
3839
}
3940
},
40-
(out int platform) =>
41-
{
42-
fixed (int* platformPtr = &platform)
43-
{
44-
return getPlatform(platformPtr, readContext);
45-
}
46-
},
4741
out ContractDescriptorTarget? target))
4842
return -1;
4943

@@ -83,4 +77,56 @@ private static unsafe int CreateSosInterface(IntPtr handle, IntPtr legacyImplPtr
8377
*obj = ptr;
8478
return 0;
8579
}
80+
81+
[UnmanagedCallersOnly(EntryPoint = "CLRDataCreateInstance")]
82+
private static unsafe int CLRDataCreateInstance(Guid* pIID, IntPtr /*ICLRDataTarget*/ pLegacyTarget, void** iface)
83+
{
84+
if (pLegacyTarget == IntPtr.Zero || iface == null)
85+
return HResults.E_INVALIDARG;
86+
87+
*iface = null;
88+
89+
ComWrappers cw = new StrategyBasedComWrappers();
90+
object obj = cw.GetOrCreateObjectForComInstance(pLegacyTarget, CreateObjectFlags.None);
91+
ICLRDataTarget dataTarget = obj as ICLRDataTarget ?? throw new ArgumentException($"pLegacyTarget does not implement ${nameof(ICLRDataTarget)}", nameof(pLegacyTarget));
92+
ICLRContractLocator contractLocator = obj as ICLRContractLocator ?? throw new ArgumentException($"pLegacyTarget does not implement ${nameof(ICLRContractLocator)}", nameof(pLegacyTarget));
93+
94+
ulong contractAddress;
95+
if (contractLocator.GetContractDescriptor(&contractAddress) != 0)
96+
{
97+
throw new InvalidOperationException("Unable to retrieve contract address from ICLRContractLocator");
98+
}
99+
100+
if (!ContractDescriptorTarget.TryCreate(
101+
contractAddress,
102+
(address, buffer) =>
103+
{
104+
fixed (byte* bufferPtr = buffer)
105+
{
106+
uint bytesRead;
107+
return dataTarget.ReadVirtual(address, bufferPtr, (uint)buffer.Length, &bytesRead);
108+
}
109+
},
110+
(threadId, contextFlags, contextSize, bufferToFill) =>
111+
{
112+
fixed (byte* bufferPtr = bufferToFill)
113+
{
114+
return dataTarget.GetThreadContext(threadId, contextFlags, contextSize, bufferPtr);
115+
}
116+
},
117+
out ContractDescriptorTarget? target))
118+
{
119+
return -1;
120+
}
121+
122+
Legacy.SOSDacImpl impl = new(target, null);
123+
nint ccw = cw.GetOrCreateComInterfaceForObject(impl, CreateComInterfaceFlags.None);
124+
Marshal.QueryInterface(ccw, *pIID, out nint ptrToIface);
125+
*iface = (void*)ptrToIface;
126+
127+
// Decrement reference count on ccw because QI increments it
128+
Marshal.Release(ccw);
129+
130+
return 0;
131+
}
86132
}

src/native/managed/cdacreader/src/Legacy/ICLRData.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,49 @@ internal unsafe partial interface ICLRDataEnumMemoryRegions
1717
[PreserveSig]
1818
int EnumMemoryRegions(/*ICLRDataEnumMemoryRegionsCallback*/ void* callback, uint miniDumpFlags, /*CLRDataEnumMemoryFlags*/ int clrFlags);
1919
}
20+
21+
[GeneratedComInterface]
22+
[Guid("3e11ccee-d08b-43e5-af01-32717a64da03")]
23+
internal unsafe partial interface ICLRDataTarget
24+
{
25+
[PreserveSig]
26+
int GetMachineType(uint* machineType);
27+
28+
[PreserveSig]
29+
int GetPointerSize(uint* pointerSize);
30+
31+
[PreserveSig]
32+
int GetImageBase([MarshalAs(UnmanagedType.LPWStr)] string imagePath, ulong* baseAddress);
33+
34+
[PreserveSig]
35+
int ReadVirtual(ulong address, byte* buffer, uint bytesRequested, uint* bytesRead);
36+
37+
[PreserveSig]
38+
int WriteVirtual(ulong address, byte* buffer, uint bytesRequested, uint* bytesWritten);
39+
40+
[PreserveSig]
41+
int GetTLSValue(uint threadID, uint index, ulong* value);
42+
43+
[PreserveSig]
44+
int SetTLSValue(uint threadID, uint index, ulong value);
45+
46+
[PreserveSig]
47+
int GetCurrentThreadID(uint* threadID);
48+
49+
[PreserveSig]
50+
int GetThreadContext(uint threadID, uint contextFlags, uint contextSize, byte* context);
51+
52+
[PreserveSig]
53+
int SetThreadContext(uint threadID, uint contextSize, byte* context);
54+
55+
[PreserveSig]
56+
int Request(uint reqCode, uint inBufferSize, byte* inBuffer, uint outBufferSize, byte* outBuffer);
57+
}
58+
59+
[GeneratedComInterface]
60+
[Guid("17d5b8c6-34a9-407f-af4f-a930201d4e02")]
61+
internal unsafe partial interface ICLRContractLocator
62+
{
63+
[PreserveSig]
64+
int GetContractDescriptor(ulong* contractAddress);
65+
}

0 commit comments

Comments
 (0)