diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 9b44cbd886a896..e4325714847bec 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -7392,6 +7392,42 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetGenericArgTokenIndex(VMPTR_Met return S_OK; } +HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetTargetInfo(OUT TargetInfo * pTargetInfo) +{ + DD_ENTER_MAY_THROW; + + if (pTargetInfo == NULL) + return E_INVALIDARG; + +#if defined(TARGET_X86) + pTargetInfo->arch = kArchX86; +#elif defined(TARGET_AMD64) + pTargetInfo->arch = kArchAMD64; +#elif defined(TARGET_ARM) + pTargetInfo->arch = kArchArm; +#elif defined(TARGET_ARM64) + pTargetInfo->arch = kArchArm64; +#elif defined(TARGET_LOONGARCH64) + pTargetInfo->arch = kArchLoongArch64; +#elif defined(TARGET_RISCV64) + pTargetInfo->arch = kArchRiscV64; +#elif defined(TARGET_WASM) + pTargetInfo->arch = kArchWasm; +#else + pTargetInfo->arch = kArchUnknown; +#endif + +#if defined(TARGET_UNIX) + pTargetInfo->os = kOSUnix; +#elif defined(TARGET_WINDOWS) + pTargetInfo->os = kOSWindows; +#else + pTargetInfo->os = kOSUnknown; +#endif + + return S_OK; +} + DacRefWalker::DacRefWalker(ClrDataAccess *dac, BOOL walkStacks, UINT32 handleMask, BOOL resolvePointers) : mDac(dac), mWalkStacks(walkStacks), mHandleMask(handleMask), mStackWalker(NULL), mResolvePointers(resolvePointers), mHandleWalker(NULL) diff --git a/src/coreclr/debug/daccess/dacdbiimpl.h b/src/coreclr/debug/daccess/dacdbiimpl.h index 23a3095166821d..0585ec51316032 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.h +++ b/src/coreclr/debug/daccess/dacdbiimpl.h @@ -151,6 +151,8 @@ class DacDbiInterfaceImpl : HRESULT STDMETHODCALLTYPE EnumerateAsyncLocals(VMPTR_MethodDesc vmMethod, CORDB_ADDRESS codeAddr, UINT32 state, FP_ASYNC_LOCAL_CALLBACK fpCallback, CALLBACK_DATA pUserData); HRESULT STDMETHODCALLTYPE GetGenericArgTokenIndex(VMPTR_MethodDesc vmMethod, OUT UINT32* pIndex); + HRESULT STDMETHODCALLTYPE GetTargetInfo(OUT TargetInfo * pTargetInfo); + private: void TypeHandleToExpandedTypeInfoImpl(AreValueTypesBoxed boxed, TypeHandle typeHandle, diff --git a/src/coreclr/debug/inc/dacdbiinterface.h b/src/coreclr/debug/inc/dacdbiinterface.h index 2b43a2cfa8eb66..3c04bbe546e956 100644 --- a/src/coreclr/debug/inc/dacdbiinterface.h +++ b/src/coreclr/debug/inc/dacdbiinterface.h @@ -2203,6 +2203,34 @@ IDacDbiInterface : public IUnknown VMPTR_MethodDesc vmMethod, OUT UINT32* pTokenIndex) = 0; + typedef enum + { + kArchUnknown = 0, + kArchX86, + kArchAMD64, + kArchArm, + kArchArm64, + kArchLoongArch64, + kArchRiscV64, + kArchWasm, + } TargetArchitecture; + + typedef enum + { + kOSUnknown = 0, + kOSWindows, + kOSUnix, + } TargetOperatingSystem; + + struct TargetInfo + { + TargetArchitecture arch; + TargetOperatingSystem os; + }; + + // Returns the target's processor architecture and OS family. + virtual HRESULT STDMETHODCALLTYPE GetTargetInfo(OUT TargetInfo * pTargetInfo) = 0; + // The following tag tells the DD-marshalling tool to stop scanning. // END_MARSHAL diff --git a/src/coreclr/inc/dacdbi.idl b/src/coreclr/inc/dacdbi.idl index 903b2ee3bd66d8..e044556bb19ebb 100644 --- a/src/coreclr/inc/dacdbi.idl +++ b/src/coreclr/inc/dacdbi.idl @@ -129,6 +129,7 @@ typedef struct { void *pList; int nEntries; } DacDbiArrayList_CORDB_ADDRESS; typedef struct { void *pList; int nEntries; } DacDbiArrayList_GUID; typedef struct { void *pList; int nEntries; } DacDbiArrayList_COR_SEGMENT; typedef struct { void *pList; int nEntries; } DacDbiArrayList_COR_MEMORY_RANGE; +typedef struct { int arch; int os; } TargetInfo; cpp_quote("#endif") @@ -436,4 +437,7 @@ interface IDacDbiInterface : IUnknown // Generic Arg Token HRESULT GetGenericArgTokenIndex([in] VMPTR_MethodDesc vmMethod, [out] UINT32 * pTokenIndex); + + // Returns the target's processor architecture and OS family. + HRESULT GetTargetInfo([out] struct TargetInfo * pTargetInfo); }; diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs index 71c973ecb6d881..52f5b36e5efe60 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs @@ -5611,6 +5611,56 @@ public int GetGenericArgTokenIndex(ulong vmMethod, uint* pIndex) return hr; } + public int GetTargetInfo(TargetInfo* pTargetInfo) + { + int hr = HResults.S_OK; + try + { + if (pTargetInfo is null) + throw new ArgumentNullException(nameof(pTargetInfo)); + + Contracts.IRuntimeInfo runtimeInfo = _target.Contracts.RuntimeInfo; + + pTargetInfo->Arch = runtimeInfo.GetTargetArchitecture() switch + { + Contracts.RuntimeInfoArchitecture.X86 => TargetArchitecture.X86, + Contracts.RuntimeInfoArchitecture.X64 => TargetArchitecture.AMD64, + Contracts.RuntimeInfoArchitecture.Arm => TargetArchitecture.Arm, + Contracts.RuntimeInfoArchitecture.Arm64 => TargetArchitecture.Arm64, + Contracts.RuntimeInfoArchitecture.LoongArch64 => TargetArchitecture.LoongArch64, + Contracts.RuntimeInfoArchitecture.RiscV64 => TargetArchitecture.RiscV64, + Contracts.RuntimeInfoArchitecture.Wasm => TargetArchitecture.Wasm, + _ => TargetArchitecture.Unknown, + }; + + pTargetInfo->OS = runtimeInfo.GetTargetOperatingSystem() switch + { + Contracts.RuntimeInfoOperatingSystem.Windows => TargetOperatingSystem.Windows, + Contracts.RuntimeInfoOperatingSystem.Unix => TargetOperatingSystem.Unix, + Contracts.RuntimeInfoOperatingSystem.Apple => TargetOperatingSystem.Unix, + _ => TargetOperatingSystem.Unknown, + }; + } + catch (System.Exception ex) + { + hr = ex.HResult; + } +#if DEBUG + if (_legacy is not null) + { + TargetInfo targetInfoLocal; + int hrLocal = _legacy.GetTargetInfo(&targetInfoLocal); + Debug.ValidateHResult(hr, hrLocal); + if (hr == HResults.S_OK) + { + Debug.Assert(pTargetInfo->Arch == targetInfoLocal.Arch, $"cDAC: {pTargetInfo->Arch}, DAC: {targetInfoLocal.Arch}"); + Debug.Assert(pTargetInfo->OS == targetInfoLocal.OS, $"cDAC: {pTargetInfo->OS}, DAC: {targetInfoLocal.OS}"); + } + } +#endif + return hr; + } + // Fills a DebuggerIPCE_ExpandedTypeData entry for a single type parameter, falling back to System.__Canon on failure. private void FillExpandedTypeDataWithCanonFallback(IRuntimeTypeSystem rts, TypeHandle typeHandle, TypeHandle thCanon, DebuggerIPCE_ExpandedTypeData* pTypeInfo) { diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/IDacDbiInterface.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/IDacDbiInterface.cs index a51ebc9d7d1c07..852f0c0cc8f7b7 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/IDacDbiInterface.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/IDacDbiInterface.cs @@ -799,4 +799,32 @@ int EnumerateAsyncLocals(ulong vmMethod, ulong codeAddr, uint state, [PreserveSig] int GetGenericArgTokenIndex(ulong vmMethod, uint* pIndex); + + [PreserveSig] + int GetTargetInfo(TargetInfo* pTargetInfo); +} + +public enum TargetArchitecture +{ + Unknown = 0, + X86, + AMD64, + Arm, + Arm64, + LoongArch64, + RiscV64, + Wasm, +} + +public enum TargetOperatingSystem +{ + Unknown = 0, + Windows, + Unix, +} + +public struct TargetInfo +{ + public TargetArchitecture Arch; + public TargetOperatingSystem OS; }