Skip to content
4 changes: 2 additions & 2 deletions src/coreclr/debug/daccess/request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -888,11 +888,11 @@ HRESULT ClrDataAccess::GetThreadData(CLRDATA_ADDRESS threadAddr, struct DacpThre
#ifdef FEATURE_EH_FUNCLETS
if (thread->m_ExceptionState.m_pCurrentTracker)
{
threadData->firstNestedException = PTR_HOST_TO_TADDR(
threadData->firstNestedException = HOST_CDADDR(
thread->m_ExceptionState.m_pCurrentTracker->m_pPrevNestedInfo);
}
#else
threadData->firstNestedException = PTR_HOST_TO_TADDR(
threadData->firstNestedException = HOST_CDADDR(
thread->m_ExceptionState.m_currentExInfo.m_pPrevNestedInfo);
#endif // FEATURE_EH_FUNCLETS

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ internal static class CodePointerUtils

internal static TargetCodePointer CodePointerFromAddress(TargetPointer address, Target target)
{
if (address == TargetPointer.Null)
{
return TargetCodePointer.Null;
}

IPlatformMetadata metadata = target.Contracts.PlatformMetadata;
CodePointerFlags flags = metadata.GetCodePointerFlags();
if (flags.HasFlag(CodePointerFlags.HasArm32ThumbBit))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ int IXCLRDataStackWalk.Request(uint reqCode, uint inBufferSize, byte* inBuffer,
IStackWalk sw = _target.Contracts.StackWalk;
IStackDataFrameHandle frameData = _dataFrames.Current;
TargetPointer frameAddr = sw.GetFrameAddress(frameData);
*(ulong*)outBuffer = frameAddr.Value;
*(ulong*)outBuffer = frameAddr.ToClrDataAddress(_target);
hr = HResults.S_OK;
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics;
using Microsoft.Diagnostics.DataContractReader.Contracts;

namespace Microsoft.Diagnostics.DataContractReader.Legacy;

internal static class ConversionExtensions
{
private const uint Arm32ThumbBit = 1;

/// <summary>
/// Converts a TargetPointer to a ClrDataAddress using sign extension if required.
/// </summary>
Expand All @@ -24,21 +28,62 @@ public static ClrDataAddress ToClrDataAddress(this TargetPointer address, Target

/// <summary>
/// Converts a ClrDataAddress to a TargetPointer, ensuring the address is within the valid range for the target platform.
/// When overrideCheck is true, this will not check the range and will allow any address. This is used on legacy endpoints which
/// may pass in invalid ClrDataAddress values.
/// </summary>
public static TargetPointer ToTargetPointer(this ClrDataAddress address, Target target)
public static TargetPointer ToTargetPointer(this ClrDataAddress address, Target target, bool overrideCheck = false)
{
if (target.PointerSize == sizeof(ulong))
{
return new TargetPointer(address);
}
else
{
long signedAddr = (long)address.Value;
if (!overrideCheck && (signedAddr > int.MaxValue || signedAddr < int.MinValue))
{
throw new ArgumentException($"ClrDataAddress 0x{address.Value:x} out of range for the target platform.", nameof(address));
}
return new TargetPointer((uint)address);
}
}

/// <summary>
/// Converts a ClrDataAddress to a TargetCodePointer, ensuring the address is within the valid range for the target platform.
/// </summary>
public static TargetCodePointer ToTargetCodePointer(this ClrDataAddress address, Target target)
{
if (target.PointerSize == sizeof(ulong))
{
return new TargetCodePointer(address);
}
else
{
long signedAddr = (long)address.Value;
if (signedAddr > int.MaxValue || signedAddr < int.MinValue)
{
throw new ArgumentException(nameof(address), "ClrDataAddress out of range for the target platform.");
throw new ArgumentException($"ClrDataAddress 0x{address.Value:x} out of range for the target platform.", nameof(address));
}
return new TargetPointer((ulong)address);
return new TargetCodePointer((uint)address);
}
}

/// <summary>
/// Converts a TargetCodePointer to an address TargetPointer, removing any platform-specific bits such as the ARM32 Thumb bit or ARM64 pointer authentication.
/// </summary>
internal static TargetPointer ToAddress(this TargetCodePointer code, Target target)
{
IPlatformMetadata metadata = target.Contracts.PlatformMetadata;
CodePointerFlags flags = metadata.GetCodePointerFlags();
if (flags.HasFlag(CodePointerFlags.HasArm32ThumbBit))
{
return new TargetPointer(code.Value & ~Arm32ThumbBit);
}
else if (flags.HasFlag(CodePointerFlags.HasArm64PtrAuth))
{
throw new NotImplementedException($"{nameof(ToAddress)}: ARM64 with pointer authentication");
}
Debug.Assert(flags == default);
return new TargetPointer(code.Value);
}
}
86 changes: 43 additions & 43 deletions src/native/managed/cdac/mscordaccore_universal/Legacy/SOSDacImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ int ISOSDacInterface.GetMethodDescData(ClrDataAddress addr, ClrDataAddress ip, D
NativeCodeVersionHandle? activeNativeCodeVersion = null;
if (ip != 0)
{
requestedNativeCodeVersion = nativeCodeContract.GetNativeCodeVersionForIP(new TargetCodePointer(ip));
requestedNativeCodeVersion = nativeCodeContract.GetNativeCodeVersionForIP(ip.ToTargetCodePointer(_target));
}
else
{
Expand All @@ -457,7 +457,7 @@ int ISOSDacInterface.GetMethodDescData(ClrDataAddress addr, ClrDataAddress ip, D
if (nativeCodeAddr != TargetCodePointer.Null)
{
data->bHasNativeCode = 1;
data->NativeCodeAddr = nativeCodeAddr.AsTargetPointer.ToClrDataAddress(_target);
data->NativeCodeAddr = nativeCodeAddr.ToAddress(_target).ToClrDataAddress(_target);
}
else
{
Expand Down Expand Up @@ -615,41 +615,41 @@ int ISOSDacInterface.GetMethodDescData(ClrDataAddress addr, ClrDataAddress ip, D
Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}");
if (hr == HResults.S_OK)
{
Debug.Assert(data->bHasNativeCode == dataLocal.bHasNativeCode);
Debug.Assert(data->bIsDynamic == dataLocal.bIsDynamic);
Debug.Assert(data->wSlotNumber == dataLocal.wSlotNumber);
Debug.Assert(data->NativeCodeAddr == dataLocal.NativeCodeAddr);
Debug.Assert(data->AddressOfNativeCodeSlot == dataLocal.AddressOfNativeCodeSlot);
Debug.Assert(data->MethodDescPtr == dataLocal.MethodDescPtr);
Debug.Assert(data->MethodTablePtr == dataLocal.MethodTablePtr);
Debug.Assert(data->ModulePtr == dataLocal.ModulePtr);
Debug.Assert(data->MDToken == dataLocal.MDToken);
Debug.Assert(data->GCInfo == dataLocal.GCInfo);
Debug.Assert(data->GCStressCodeCopy == dataLocal.GCStressCodeCopy);
Debug.Assert(data->bHasNativeCode == dataLocal.bHasNativeCode, $"cDAC: {data->bHasNativeCode}, DAC: {dataLocal.bHasNativeCode}");
Debug.Assert(data->bIsDynamic == dataLocal.bIsDynamic, $"cDAC: {data->bIsDynamic}, DAC: {dataLocal.bIsDynamic}");
Debug.Assert(data->wSlotNumber == dataLocal.wSlotNumber, $"cDAC: {data->wSlotNumber}, DAC: {dataLocal.wSlotNumber}");
Debug.Assert(data->NativeCodeAddr == dataLocal.NativeCodeAddr, $"cDAC: {data->NativeCodeAddr:x}, DAC: {dataLocal.NativeCodeAddr:x}");
Debug.Assert(data->AddressOfNativeCodeSlot == dataLocal.AddressOfNativeCodeSlot, $"cDAC: {data->AddressOfNativeCodeSlot:x}, DAC: {dataLocal.AddressOfNativeCodeSlot:x}");
Debug.Assert(data->MethodDescPtr == dataLocal.MethodDescPtr, $"cDAC: {data->MethodDescPtr:x}, DAC: {dataLocal.MethodDescPtr:x}");
Debug.Assert(data->MethodTablePtr == dataLocal.MethodTablePtr, $"cDAC: {data->MethodTablePtr:x}, DAC: {dataLocal.MethodTablePtr:x}");
Debug.Assert(data->ModulePtr == dataLocal.ModulePtr, $"cDAC: {data->ModulePtr:x}, DAC: {dataLocal.ModulePtr:x}");
Debug.Assert(data->MDToken == dataLocal.MDToken, $"cDAC: {data->MDToken:x}, DAC: {dataLocal.MDToken:x}");
Debug.Assert(data->GCInfo == dataLocal.GCInfo, $"cDAC: {data->GCInfo:x}, DAC: {dataLocal.GCInfo:x}");
Debug.Assert(data->GCStressCodeCopy == dataLocal.GCStressCodeCopy, $"cDAC: {data->GCStressCodeCopy:x}, DAC: {dataLocal.GCStressCodeCopy:x}");
// managedDynamicMethodObject is not currently populated by the cDAC API and may differ from legacyImpl.
Debug.Assert(data->managedDynamicMethodObject == 0);
Debug.Assert(data->requestedIP == dataLocal.requestedIP);
Debug.Assert(data->cJittedRejitVersions == dataLocal.cJittedRejitVersions);
Debug.Assert(data->requestedIP == dataLocal.requestedIP, $"cDAC: {data->requestedIP:x}, DAC: {dataLocal.requestedIP:x}");
Debug.Assert(data->cJittedRejitVersions == dataLocal.cJittedRejitVersions, $"cDAC: {data->cJittedRejitVersions}, DAC: {dataLocal.cJittedRejitVersions}");

// rejitDataCurrent
Debug.Assert(data->rejitDataCurrent.rejitID == dataLocal.rejitDataCurrent.rejitID);
Debug.Assert(data->rejitDataCurrent.NativeCodeAddr == dataLocal.rejitDataCurrent.NativeCodeAddr);
Debug.Assert(data->rejitDataCurrent.flags == dataLocal.rejitDataCurrent.flags);
Debug.Assert(data->rejitDataCurrent.rejitID == dataLocal.rejitDataCurrent.rejitID, $"cDAC: {data->rejitDataCurrent.rejitID}, DAC: {dataLocal.rejitDataCurrent.rejitID}");
Debug.Assert(data->rejitDataCurrent.NativeCodeAddr == dataLocal.rejitDataCurrent.NativeCodeAddr, $"cDAC: {data->rejitDataCurrent.NativeCodeAddr:x}, DAC: {dataLocal.rejitDataCurrent.NativeCodeAddr:x}");
Debug.Assert(data->rejitDataCurrent.flags == dataLocal.rejitDataCurrent.flags, $"cDAC: {data->rejitDataCurrent.flags}, DAC: {dataLocal.rejitDataCurrent.flags}");

// rejitDataRequested
Debug.Assert(data->rejitDataRequested.rejitID == dataLocal.rejitDataRequested.rejitID);
Debug.Assert(data->rejitDataRequested.NativeCodeAddr == dataLocal.rejitDataRequested.NativeCodeAddr);
Debug.Assert(data->rejitDataRequested.flags == dataLocal.rejitDataRequested.flags);
Debug.Assert(data->rejitDataRequested.rejitID == dataLocal.rejitDataRequested.rejitID, $"cDAC: {data->rejitDataRequested.rejitID}, DAC: {dataLocal.rejitDataRequested.rejitID}");
Debug.Assert(data->rejitDataRequested.NativeCodeAddr == dataLocal.rejitDataRequested.NativeCodeAddr, $"cDAC: {data->rejitDataRequested.NativeCodeAddr:x}, DAC: {dataLocal.rejitDataRequested.NativeCodeAddr:x}");
Debug.Assert(data->rejitDataRequested.flags == dataLocal.rejitDataRequested.flags, $"cDAC: {data->rejitDataRequested.flags}, DAC: {dataLocal.rejitDataRequested.flags}");

// rgRevertedRejitData
if (rgRevertedRejitData != null && rgRevertedRejitDataLocal != null)
{
Debug.Assert(cNeededRevertedRejitDataLocal == *pcNeededRevertedRejitData);
Debug.Assert(cNeededRevertedRejitDataLocal == *pcNeededRevertedRejitData, $"cDAC: {*pcNeededRevertedRejitData}, DAC: {cNeededRevertedRejitDataLocal}");
for (ulong i = 0; i < cNeededRevertedRejitDataLocal; i++)
{
Debug.Assert(rgRevertedRejitData[i].rejitID == rgRevertedRejitDataLocal[i].rejitID);
Debug.Assert(rgRevertedRejitData[i].NativeCodeAddr == rgRevertedRejitDataLocal[i].NativeCodeAddr);
Debug.Assert(rgRevertedRejitData[i].flags == rgRevertedRejitDataLocal[i].flags);
Debug.Assert(rgRevertedRejitData[i].rejitID == rgRevertedRejitDataLocal[i].rejitID, $"cDAC: {rgRevertedRejitData[i].rejitID}, DAC: {rgRevertedRejitDataLocal[i].rejitID}");
Debug.Assert(rgRevertedRejitData[i].NativeCodeAddr == rgRevertedRejitDataLocal[i].NativeCodeAddr, $"cDAC: {rgRevertedRejitData[i].NativeCodeAddr:x}, DAC: {rgRevertedRejitDataLocal[i].NativeCodeAddr:x}");
Debug.Assert(rgRevertedRejitData[i].flags == rgRevertedRejitDataLocal[i].flags, $"cDAC: {rgRevertedRejitData[i].flags}, DAC: {rgRevertedRejitDataLocal[i].flags}");
}
}
}
Expand Down Expand Up @@ -803,7 +803,7 @@ int ISOSDacInterface.GetMethodDescPtrFromIP(ClrDataAddress ip, ClrDataAddress* p
IExecutionManager executionManager = _target.Contracts.ExecutionManager;
IRuntimeTypeSystem rts = _target.Contracts.RuntimeTypeSystem;

CodeBlockHandle? handle = executionManager.GetCodeBlockHandle(new TargetCodePointer(ip));
CodeBlockHandle? handle = executionManager.GetCodeBlockHandle(ip.ToTargetCodePointer(_target));
if (handle is CodeBlockHandle codeHandle)
{
TargetPointer methodDescAddr = executionManager.GetMethodDesc(codeHandle);
Expand All @@ -814,7 +814,7 @@ int ISOSDacInterface.GetMethodDescPtrFromIP(ClrDataAddress ip, ClrDataAddress* p
// if validation fails, should return E_INVALIDARG
rts.GetMethodDescHandle(methodDescAddr);

*ppMD = methodDescAddr.Value;
*ppMD = methodDescAddr.ToClrDataAddress(_target);
hr = HResults.S_OK;
}
catch (System.Exception)
Expand Down Expand Up @@ -963,7 +963,7 @@ int ISOSDacInterface.GetMethodTableName(ClrDataAddress mt, uint count, char* mtN
try
{
Contracts.IRuntimeTypeSystem typeSystemContract = _target.Contracts.RuntimeTypeSystem;
Contracts.TypeHandle methodTableHandle = typeSystemContract.GetTypeHandle(mt.ToTargetPointer(_target));
Contracts.TypeHandle methodTableHandle = typeSystemContract.GetTypeHandle(mt.ToTargetPointer(_target, overrideCheck: true));
if (typeSystemContract.IsFreeObjectMethodTable(methodTableHandle))
{
OutputBufferHelpers.CopyStringToBuffer(mtName, count, pNeeded, "Free");
Expand Down Expand Up @@ -1511,21 +1511,21 @@ int ISOSDacInterface.GetThreadData(ClrDataAddress thread, DacpThreadData* data)
Debug.Assert(hrLocal == hr, $"cDAC: {hr:x}, DAC: {hrLocal:x}");
if (hr == HResults.S_OK)
{
Debug.Assert(data->corThreadId == dataLocal.corThreadId);
Debug.Assert(data->osThreadId == dataLocal.osThreadId);
Debug.Assert(data->state == dataLocal.state);
Debug.Assert(data->preemptiveGCDisabled == dataLocal.preemptiveGCDisabled);
Debug.Assert(data->allocContextPtr == dataLocal.allocContextPtr);
Debug.Assert(data->allocContextLimit == dataLocal.allocContextLimit);
Debug.Assert(data->fiberData == dataLocal.fiberData);
Debug.Assert(data->context == dataLocal.context);
Debug.Assert(data->domain == dataLocal.domain);
Debug.Assert(data->lockCount == dataLocal.lockCount);
Debug.Assert(data->pFrame == dataLocal.pFrame);
Debug.Assert(data->firstNestedException == dataLocal.firstNestedException);
Debug.Assert(data->teb == dataLocal.teb);
Debug.Assert(data->lastThrownObjectHandle == dataLocal.lastThrownObjectHandle);
Debug.Assert(data->nextThread == dataLocal.nextThread);
Debug.Assert(data->corThreadId == dataLocal.corThreadId, $"cDAC: {data->corThreadId}, DAC: {dataLocal.corThreadId}");
Debug.Assert(data->osThreadId == dataLocal.osThreadId, $"cDAC: {data->osThreadId}, DAC: {dataLocal.osThreadId}");
Debug.Assert(data->state == dataLocal.state, $"cDAC: {data->state}, DAC: {dataLocal.state}");
Debug.Assert(data->preemptiveGCDisabled == dataLocal.preemptiveGCDisabled, $"cDAC: {data->preemptiveGCDisabled}, DAC: {dataLocal.preemptiveGCDisabled}");
Debug.Assert(data->allocContextPtr == dataLocal.allocContextPtr, $"cDAC: {data->allocContextPtr:x}, DAC: {dataLocal.allocContextPtr:x}");
Debug.Assert(data->allocContextLimit == dataLocal.allocContextLimit, $"cDAC: {data->allocContextLimit:x}, DAC: {dataLocal.allocContextLimit:x}");
Debug.Assert(data->fiberData == dataLocal.fiberData, $"cDAC: {data->fiberData:x}, DAC: {dataLocal.fiberData:x}");
Debug.Assert(data->context == dataLocal.context, $"cDAC: {data->context:x}, DAC: {dataLocal.context:x}");
Debug.Assert(data->domain == dataLocal.domain, $"cDAC: {data->domain:x}, DAC: {dataLocal.domain:x}");
Debug.Assert(data->lockCount == dataLocal.lockCount, $"cDAC: {data->lockCount}, DAC: {dataLocal.lockCount}");
Debug.Assert(data->pFrame == dataLocal.pFrame, $"cDAC: {data->pFrame:x}, DAC: {dataLocal.pFrame:x}");
Debug.Assert(data->firstNestedException == dataLocal.firstNestedException, $"cDAC: {data->firstNestedException:x}, DAC: {dataLocal.firstNestedException:x}");
Debug.Assert(data->teb == dataLocal.teb, $"cDAC: {data->teb:x}, DAC: {dataLocal.teb:x}");
Debug.Assert(data->lastThrownObjectHandle == dataLocal.lastThrownObjectHandle, $"cDAC: {data->lastThrownObjectHandle:x}, DAC: {dataLocal.lastThrownObjectHandle:x}");
Debug.Assert(data->nextThread == dataLocal.nextThread, $"cDAC: {data->nextThread:x}, DAC: {dataLocal.nextThread:x}");
}
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/native/managed/compile-native.proj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<SupportsNativeAotComponents Condition="'$(SupportsNativeAotComponents)' == '' and '$(HostOS)' != '$(TargetOS)'">false</SupportsNativeAotComponents>
<!-- unsupported targets -->
<SupportsNativeAotComponents Condition="'$(SupportsNativeAotComponents)' == '' and '$(DotNetBuildSourceOnly)' == 'true'">false</SupportsNativeAotComponents>
<SupportsNativeAotComponents Condition="'$(SupportsNativeAotComponents)' == '' and ('$(TargetArchitecture)' == 'arm' or '$(TargetArchitecture)' == 'armel' or '$(TargetArchitecture)' == 'riscv64')">false</SupportsNativeAotComponents>
<SupportsNativeAotComponents Condition="'$(SupportsNativeAotComponents)' == '' and ('$(TargetArchitecture)' == 'armel' or '$(TargetArchitecture)' == 'riscv64')">false</SupportsNativeAotComponents>
<SupportsNativeAotComponents Condition="'$(SupportsNativeAotComponents)' == '' and ('$(TargetsWindows)' == 'true' or '$(TargetsOSX)' == 'true' or ('$(TargetsLinux)' == 'true' and '$(TargetsAndroid)' != 'true' and '$(TargetsLinuxMusl)' != 'true'))">true</SupportsNativeAotComponents>
<SupportsNativeAotComponents Condition="'$(SupportsNativeAotComponents)' == ''">false</SupportsNativeAotComponents>
</PropertyGroup>
Expand Down
Loading