From 60df83d502c402526c048ffb6eb8c53ecfebc0e3 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Wed, 8 Jul 2026 13:42:18 -0700 Subject: [PATCH 01/26] Add GetTargetInfo DacDbi API Introduces IDacDbiInterface::GetTargetInfo, which reports the target's processor architecture and OS family, along with the TargetInfo/TargetArchitecture/TargetOperatingSystem types. Includes the native DAC implementation and the managed cDAC implementation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/coreclr/debug/daccess/dacdbiimpl.cpp | 36 +++++++++++++ src/coreclr/debug/daccess/dacdbiimpl.h | 2 + src/coreclr/debug/inc/dacdbiinterface.h | 28 +++++++++++ src/coreclr/inc/dacdbi.idl | 4 ++ .../Dbi/DacDbiImpl.cs | 50 +++++++++++++++++++ .../Dbi/IDacDbiInterface.cs | 28 +++++++++++ 6 files changed, 148 insertions(+) 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; } From dd951b9dce7134c93071984b9192186a501da708 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Wed, 8 Jul 2026 21:08:15 -0700 Subject: [PATCH 02/26] remove target dependent stuff --- src/coreclr/debug/daccess/daccess.cpp | 49 --- src/coreclr/debug/daccess/dacdbiimpl.cpp | 6 + src/coreclr/debug/di/cordb.cpp | 2 +- src/coreclr/debug/di/module.cpp | 4 +- src/coreclr/debug/di/platformspecific.cpp | 12 +- src/coreclr/debug/di/process.cpp | 62 ++- src/coreclr/debug/di/rsmain.cpp | 2 +- src/coreclr/debug/di/rspriv.h | 21 +- src/coreclr/debug/di/rsthread.cpp | 382 +++++++++--------- src/coreclr/debug/di/rstype.cpp | 2 - src/coreclr/debug/di/shimdatatarget.h | 6 + src/coreclr/debug/di/shimlocaldatatarget.cpp | 15 +- src/coreclr/debug/di/shimpriv.h | 2 +- src/coreclr/debug/di/shimprocess.cpp | 1 + src/coreclr/debug/di/shimremotedatatarget.cpp | 72 ++-- src/coreclr/debug/di/shimstackwalk.cpp | 22 +- src/coreclr/debug/di/valuehome.cpp | 35 +- src/coreclr/debug/inc/dacdbiinterface.h | 3 +- src/coreclr/inc/dacdbi.idl | 2 +- 19 files changed, 338 insertions(+), 362 deletions(-) diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index df4f4defa29c6d..62f65d572e3052 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -5099,55 +5099,6 @@ ClrDataAccess::Initialize(void) HRESULT hr; CLRDATA_ADDRESS base = { 0 }; - // - // We do not currently support cross-platform - // debugging. Verify that cross-platform is not - // being attempted. - // - - // Determine our platform based on the pre-processor macros set when we were built - -#ifdef TARGET_UNIX - #if defined(TARGET_X86) - CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_X86; - #elif defined(TARGET_AMD64) - CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_AMD64; - #elif defined(TARGET_ARM) - CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_ARM; - #elif defined(TARGET_ARM64) - CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_ARM64; - #elif defined(TARGET_LOONGARCH64) - CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_LOONGARCH64; - #elif defined(TARGET_RISCV64) - CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_RISCV64; - #else - #error Unknown Processor. - #endif -#else - #if defined(TARGET_X86) - CorDebugPlatform hostPlatform = CORDB_PLATFORM_WINDOWS_X86; - #elif defined(TARGET_AMD64) - CorDebugPlatform hostPlatform = CORDB_PLATFORM_WINDOWS_AMD64; - #elif defined(TARGET_ARM) - CorDebugPlatform hostPlatform = CORDB_PLATFORM_WINDOWS_ARM; - #elif defined(TARGET_ARM64) - CorDebugPlatform hostPlatform = CORDB_PLATFORM_WINDOWS_ARM64; - #else - #error Unknown Processor. - #endif -#endif - - CorDebugPlatform targetPlatform; - IfFailRet(m_pTarget->GetPlatform(&targetPlatform)); - - if (targetPlatform != hostPlatform) - { - // DAC fatal error: Platform mismatch - the platform reported by the data target - // is not what this version of mscordacwks.dll was built for. - return CORDBG_E_INCOMPATIBLE_PLATFORMS; - } - - // // Get the current DLL base for mscorwks globals. // In case of multiple-CLRs, there may be multiple dlls named "mscorwks". // code:OpenVirtualProcess can take the base address (clrInstanceId) to select exactly diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index e4325714847bec..9c1d40d99c4105 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -7425,6 +7425,12 @@ HRESULT STDMETHODCALLTYPE DacDbiInterfaceImpl::GetTargetInfo(OUT TargetInfo * pT pTargetInfo->os = kOSUnknown; #endif +#if defined(TARGET_64BIT) + pTargetInfo->pointerSize = 8; +#else + pTargetInfo->pointerSize = 4; +#endif + return S_OK; } diff --git a/src/coreclr/debug/di/cordb.cpp b/src/coreclr/debug/di/cordb.cpp index 036ae1fb217491..657ddcb4eecec8 100644 --- a/src/coreclr/debug/di/cordb.cpp +++ b/src/coreclr/debug/di/cordb.cpp @@ -18,7 +18,7 @@ #include "dbgtransportmanager.h" #endif // FEATURE_DBGIPC_TRANSPORT_DI -#if defined(TARGET_UNIX) || defined(__ANDROID__) +#if defined(HOST_UNIX) || defined(__ANDROID__) // Local (in-process) debugging is not supported for UNIX and Android. #define SUPPORT_LOCAL_DEBUGGING 0 #else diff --git a/src/coreclr/debug/di/module.cpp b/src/coreclr/debug/di/module.cpp index 052dc4413676da..2f83b292bc959a 100644 --- a/src/coreclr/debug/di/module.cpp +++ b/src/coreclr/debug/di/module.cpp @@ -883,7 +883,7 @@ HRESULT CordbModule::InitPublicMetaDataFromFile(const WCHAR * pszFullPathName, } return hr; -#endif // TARGET_UNIX +#endif // HOST_UNIX } //--------------------------------------------------------------------------------------- @@ -2412,7 +2412,7 @@ HRESULT CordbModule::CreateReaderForInMemorySymbols(REFIID riid, void** ppObj) ReleaseHolder pBinder; if (symFormat == IDacDbiInterface::kSymbolFormatPDB) { -#ifndef TARGET_UNIX +#ifndef HOST_UNIX // PDB format - use diasymreader.dll with COM activation InlineSString ssBuf; IfFailThrow(GetClrModuleDirectory(ssBuf)); diff --git a/src/coreclr/debug/di/platformspecific.cpp b/src/coreclr/debug/di/platformspecific.cpp index cd690dccc2fd25..e26cacb7b149df 100644 --- a/src/coreclr/debug/di/platformspecific.cpp +++ b/src/coreclr/debug/di/platformspecific.cpp @@ -21,22 +21,22 @@ #include "localeventchannel.cpp" #endif -#if TARGET_X86 +#if HOST_X86 #include "i386/cordbregisterset.cpp" #include "i386/primitives.cpp" -#elif TARGET_AMD64 +#elif HOST_AMD64 #include "amd64/cordbregisterset.cpp" #include "amd64/primitives.cpp" -#elif TARGET_ARM +#elif HOST_ARM #include "arm/cordbregisterset.cpp" #include "arm/primitives.cpp" -#elif TARGET_ARM64 +#elif HOST_ARM64 #include "arm64/cordbregisterset.cpp" #include "arm64/primitives.cpp" -#elif TARGET_LOONGARCH64 +#elif HOST_LOONGARCH64 #include "loongarch64/cordbregisterset.cpp" #include "loongarch64/primitives.cpp" -#elif TARGET_RISCV64 +#elif HOST_RISCV64 #include "riscv64/cordbregisterset.cpp" #include "riscv64/primitives.cpp" #else diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index cf1dc0d0ee0571..0b901000268944 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -178,11 +178,11 @@ STDAPI DLLEXPORT OpenVirtualProcessImpl2( IUnknown ** ppInstance, CLR_DEBUGGING_PROCESS_FLAGS* pFlagsOut) { -#ifdef TARGET_WINDOWS +#ifdef HOST_WINDOWS HMODULE hDac = WszLoadLibrary(pDacModulePath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); #else HMODULE hDac = WszLoadLibrary(pDacModulePath); -#endif // !TARGET_WINDOWS +#endif // !HOST_WINDOWS if (hDac == NULL) { return HRESULT_FROM_WIN32(GetLastError()); @@ -648,6 +648,33 @@ IDacDbiInterface * CordbProcess::GetDAC() return m_pDacPrimitives; } +HRESULT CordbProcess::GetTargetInfo(IDacDbiInterface::TargetInfo * pTargetInfo) +{ + CONTRACTL + { + THROWS; + } + CONTRACTL_END; + + if (pTargetInfo == NULL) + return E_INVALIDARG; + + HRESULT hr = S_OK; + EX_TRY + { + if (!m_fHasCachedTargetInfo) + { + IfFailThrow(GetDAC()->GetTargetInfo(&m_cachedTargetInfo)); + m_fHasCachedTargetInfo = true; + } + + *pTargetInfo = m_cachedTargetInfo; + } + EX_CATCH_HRESULT(hr); + + return hr; +} + //--------------------------------------------------------------------------------------- // Get the Data-Target // @@ -852,6 +879,7 @@ CordbProcess::CordbProcess(ULONG64 clrInstanceId, m_dispatchedEvent(DB_IPCE_DEBUGGER_INVALID), m_hDacModule(hDacModule), m_pDacPrimitives(NULL), + m_fHasCachedTargetInfo(false), m_pEventChannel(NULL), m_fAssertOnTargetInconsistency(false), m_runtimeOffsetsInitialized(false), @@ -6582,7 +6610,7 @@ HRESULT CordbProcess::FindPatchByAddress(CORDB_ADDRESS address, bool *pfPatchFou if (*pfPatchFound == false) { // Read one instruction from the faulting address... -#if defined(TARGET_ARM) || defined(TARGET_ARM64) +#if defined(HOST_ARM) || defined(HOST_ARM64) PRD_TYPE TrapCheck = 0; #else BYTE TrapCheck = 0; @@ -6627,7 +6655,7 @@ HRESULT CordbProcess::WriteMemory(CORDB_ADDRESS address, DWORD size, DWORD fCheckInt3 = configCheckInt3.val(CLRConfig::INTERNAL_DbgCheckInt3); if (fCheckInt3) { -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(HOST_X86) || defined(HOST_AMD64) if (size == 1 && buffer[0] == 0xCC) { CONSISTENCY_CHECK_MSGF(false, @@ -6636,7 +6664,7 @@ HRESULT CordbProcess::WriteMemory(CORDB_ADDRESS address, DWORD size, "(This assert is only enabled under the CLR knob DbgCheckInt3.)\n", CORDB_ADDRESS_TO_PTR(address))); } -#endif // TARGET_X86 || TARGET_AMD64 +#endif // HOST_X86 || HOST_AMD64 // check if we're replaced an opcode. if (size == 1) @@ -7074,7 +7102,7 @@ HRESULT CordbProcess::GetRuntimeOffsets() { -#if TARGET_UNIX +#if HOST_UNIX m_hHelperThread = NULL; //RS is supposed to be able to live without a helper thread handle. #else m_hHelperThread = OpenThread(SYNCHRONIZE, FALSE, dwHelperTid); @@ -8332,9 +8360,9 @@ bool CordbProcess::IsBreakOpcodeAtAddress(const void * address) { // There should have been an int3 there already. Since we already put it in there, // we should be able to safely read it out. -#if defined(TARGET_ARM) || defined(TARGET_ARM64) +#if defined(HOST_ARM) || defined(HOST_ARM64) PRD_TYPE opcodeTest = 0; -#elif defined(TARGET_AMD64) || defined(TARGET_X86) +#elif defined(HOST_AMD64) || defined(HOST_X86) BYTE opcodeTest = 0; #else PORTABILITY_ASSERT("NYI: Architecture specific opcode type to read"); @@ -8397,10 +8425,10 @@ CordbProcess::SetUnmanagedBreakpointInternal(CORDB_ADDRESS address, ULONG32 bufs HRESULT hr = S_OK; NativePatch * p = NULL; -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(HOST_X86) || defined(HOST_AMD64) const BYTE patch = CORDbg_BREAK_INSTRUCTION; BYTE opcode; -#elif defined(TARGET_ARM64) +#elif defined(HOST_ARM64) const PRD_TYPE patch = CORDbg_BREAK_INSTRUCTION; PRD_TYPE opcode; #else @@ -8439,10 +8467,10 @@ CordbProcess::SetUnmanagedBreakpointInternal(CORDB_ADDRESS address, ULONG32 bufs goto ErrExit; // It's all successful, so now update our out-params & internal bookkeaping. -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(HOST_X86) || defined(HOST_AMD64) opcode = (BYTE)p->opcode; buffer[0] = opcode; -#elif defined(TARGET_ARM64) +#elif defined(HOST_ARM64) opcode = p->opcode; memcpy_s(buffer, bufsize, &opcode, sizeof(opcode)); #else @@ -10341,7 +10369,7 @@ bool CordbProcess::HandleSetThreadContextNeeded(DWORD dwThreadId) { LOG((LF_CORDB, LL_INFO10000, "RS HandleSetThreadContextNeeded\n")); -#if defined(TARGET_WINDOWS) && defined(TARGET_AMD64) +#if defined(HOST_WINDOWS) && defined(HOST_AMD64) // Before we can read the left side context information, we must: // 1. obtain the thread handle // 2. suspened the thread @@ -12451,9 +12479,9 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven tempDebugContext.ContextFlags = DT_CONTEXT_FULL; DbiGetThreadContext(pUnmanagedThread->m_handle, &tempDebugContext); CordbUnmanagedThread::LogContext(&tempDebugContext); -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(HOST_X86) || defined(HOST_AMD64) const ULONG_PTR breakpointOpcodeSize = 1; -#elif defined(TARGET_ARM64) +#elif defined(HOST_ARM64) const ULONG_PTR breakpointOpcodeSize = 4; #else const ULONG_PTR breakpointOpcodeSize = 1; @@ -12674,7 +12702,7 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven // Because hijacks don't return normally they might have pushed handlers without poping them // back off. To take care of that we explicitly restore the old SEH chain. - #ifdef TARGET_X86 + #ifdef HOST_X86 hr = pUnmanagedThread->RestoreLeafSeh(); _ASSERTE(SUCCEEDED(hr)); #endif @@ -13081,7 +13109,7 @@ void EnableDebugTrace(CordbUnmanagedThread *ut) return; // Give us a nop so that we can setip in the optimized case. -#ifdef TARGET_X86 +#ifdef HOST_X86 __asm { nop } diff --git a/src/coreclr/debug/di/rsmain.cpp b/src/coreclr/debug/di/rsmain.cpp index c7d5c5a9e24e49..7501d3f45e799b 100644 --- a/src/coreclr/debug/di/rsmain.cpp +++ b/src/coreclr/debug/di/rsmain.cpp @@ -508,7 +508,7 @@ void CordbCommonBase::InitializeCommon() // setting this since V1.0 and removing it may be a breaking change. void CordbCommonBase::AddDebugPrivilege() { -#ifndef TARGET_UNIX +#ifndef HOST_UNIX HANDLE hToken; TOKEN_PRIVILEGES Privileges; BOOL fSucc; diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index 8265686253887c..d009aa1a5031c5 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -2860,6 +2860,8 @@ class IProcessShimHooks virtual bool IsThreadSuspendedOrHijacked(ICorDebugThread * pThread) = 0; + virtual HRESULT GetTargetInfo(IDacDbiInterface::TargetInfo * pTargetInfo) = 0; + #ifdef FEATURE_INTEROP_DEBUGGING virtual bool IsUnmanagedThreadHijacked(ICorDebugThread * pICorDebugThread) = 0; #endif @@ -3598,6 +3600,8 @@ class CordbProcess : // Get the DAC interface. IDacDbiInterface * GetDAC(); + HRESULT GetTargetInfo(IDacDbiInterface::TargetInfo * pTargetInfo); + // Get the data-target, which provides access to the debuggee. ICorDebugDataTarget * GetDataTarget(); @@ -3961,7 +3965,7 @@ class CordbProcess : PRD_TYPE *m_rgUncommittedOpcode; // CORDB_ADDRESS's are UINT_PTR's (64 bit under HOST_64BIT, 32 bit otherwise) -#if defined(TARGET_64BIT) +#if defined(HOST_64BIT) #define MAX_ADDRESS (UINT64_MAX) #else #define MAX_ADDRESS (UINT32_MAX) @@ -4086,6 +4090,9 @@ class CordbProcess : IDacDbiInterface * m_pDacPrimitives; + IDacDbiInterface::TargetInfo m_cachedTargetInfo; + bool m_fHasCachedTargetInfo; + IEventChannel * m_pEventChannel; // If true, then we'll ASSERT if we detect the target is corrupt or inconsistent @@ -4770,11 +4777,9 @@ class CordbType : public CordbBase, public ICorDebugType, public ICorDebugType2 // Is this type a GC-root. bool IsGCRoot(); -#ifdef FEATURE_64BIT_ALIGNMENT // checks if the type requires 8-byte alignment. // this is not exposed via ICorDebug at present. HRESULT RequiresAlign8(BOOL* isRequired); -#endif //----------------------------------------------------------- // Data members @@ -10416,7 +10421,7 @@ class CordbUnmanagedThread : public CordbBase return (DWORD) this->m_id; } -#ifdef TARGET_X86 +#ifdef HOST_X86 // Stores the thread's current leaf SEH handler HRESULT SaveCurrentLeafSeh(); // Restores the thread's leaf SEH handler from the previously saved value @@ -10464,7 +10469,7 @@ class CordbUnmanagedThread : public CordbBase ULONG_PTR m_raiseExceptionExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; -#ifdef TARGET_X86 +#ifdef HOST_X86 // the SEH handler which was the leaf when SaveCurrentSeh was called (prior to hijack) REMOTE_PTR m_pSavedLeafSeh; #endif @@ -11306,17 +11311,13 @@ inline void ValidateOrThrow(const void * p) // aligns argBase on platforms that require it else it's a no-op inline void AlignAddressForType(CordbType* pArgType, CORDB_ADDRESS& argBase) { -#ifdef TARGET_ARM -// TODO: review the following #ifdef FEATURE_64BIT_ALIGNMENT BOOL align = FALSE; HRESULT hr = pArgType->RequiresAlign8(&align); - _ASSERTE(SUCCEEDED(hr)); if (align) argBase = ALIGN_ADDRESS(argBase, 8); -#endif // FEATURE_64BIT_ALIGNMENT -#endif // TARGET_ARM +#endif } //----------------------------------------------------------------------------- diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index 3eb4ee573fdb37..4ea6a7f2fe7a94 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -1393,13 +1393,10 @@ HRESULT CordbThread::FindFrame(ICorDebugFrame ** ppFrame, FramePointer fp) ICorDebugFrame * pIFrame = pSSW->GetFrame(i); CordbFrame * pCFrame = CordbFrame::GetCordbFrameFromInterface(pIFrame); -#if !defined(TARGET_X86) - // Compare the FramePointer to determine if the frame matches - if (pCFrame->GetFramePointer() == fp) -#else - // On x86 we need to do a more elaborate check. The reason is that on x86, the FramePointer is always the same as the value of EBP, so we can just check if the input FramePointer is contained in the frame. However, on other platforms, the FramePointer may not be the same as the value of RSP, so we need to check if the input FramePointer is the same as the one of the frame. - if (pCFrame->IsContainedInFrame(fp)) -#endif + IDacDbiInterface::TargetInfo targetInfo; + GetProcess()->GetTargetInfo(&targetInfo); + bool frameMatches = targetInfo.arch == IDacDbiInterface::kArchX86 ? pCFrame->IsContainedInFrame(fp) : pCFrame->GetFramePointer() == fp; + if (frameMatches) { *ppFrame = pIFrame; (*ppFrame)->AddRef(); @@ -2734,7 +2731,7 @@ CordbUnmanagedThread::CordbUnmanagedThread(CordbProcess *pProcess, DWORD dwThrea m_pTLSExtendedArray(NULL), m_state(CUTS_None), m_originalHandler(NULL), -#ifdef TARGET_X86 +#ifdef HOST_X86 m_pSavedLeafSeh(NULL), #endif m_continueCountCached(0) @@ -2873,7 +2870,7 @@ VOID CordbUnmanagedThread::VerifyFSChain() return; }*/ -#ifdef TARGET_X86 +#ifdef HOST_X86 HRESULT CordbUnmanagedThread::SaveCurrentLeafSeh() { _ASSERTE(m_pSavedLeafSeh == NULL); @@ -3599,26 +3596,26 @@ VOID CordbUnmanagedThread::EndStepping() // Writes some details of the given context into the debugger log VOID CordbUnmanagedThread::LogContext(DT_CONTEXT* pContext) { -#if defined(TARGET_X86) +#if defined(HOST_X86) LOG((LF_CORDB, LL_INFO10000, "CUT::LC: Eip=0x%08x, Esp=0x%08x, Eflags=0x%08x\n", pContext->Eip, pContext->Esp, pContext->EFlags)); -#elif defined(TARGET_AMD64) +#elif defined(HOST_AMD64) LOG((LF_CORDB, LL_INFO10000, "CUT::LC: Rip=" FMT_ADDR ", Rsp=" FMT_ADDR ", Eflags=0x%08x\n", DBG_ADDR(pContext->Rip), DBG_ADDR(pContext->Rsp), pContext->EFlags)); // EFlags is still 32bits on AMD64 -#elif defined(TARGET_ARM64) +#elif defined(HOST_ARM64) LOG((LF_CORDB, LL_INFO10000, "CUT::LC: Pc=" FMT_ADDR ", Sp=" FMT_ADDR ", Lr=" FMT_ADDR ", Cpsr=" FMT_ADDR "\n", DBG_ADDR(pContext->Pc), DBG_ADDR(pContext->Sp), DBG_ADDR(pContext->Lr), DBG_ADDR(pContext->Cpsr))); -#else // TARGET_X86 +#else PORTABILITY_ASSERT("LogContext needs a PC and stack pointer."); -#endif // TARGET_X86 +#endif } // Hijacks this thread using the FirstChanceSuspend hijack @@ -3758,7 +3755,7 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijack(EHijackReason::EHijackReaso { // We save off the SEH handler on X86 to make sure we restore it properly after the hijack is complete // The hijacks don't return normally and the SEH chain might have handlers added that don't get removed by default -#ifdef TARGET_X86 +#ifdef HOST_X86 hr = SaveCurrentLeafSeh(); if(FAILED(hr)) ThrowHR(hr); @@ -3814,55 +3811,57 @@ HRESULT CordbUnmanagedThread::SetupGenericHijack(DWORD eventCode, const EXCEPTIO return HRESULT_FROM_WIN32(GetLastError()); } -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) - - // On X86 Debugger::GenericHijackFunc() ensures the stack is walkable - // by simply using the EBP chain, therefore we can execute the hijack - // by setting the thread's context EIP to point to this function. - // On X64, however, we first attempt to set up a "proper" hijack, with - // a function that allows the OS to unwind the stack (ExceptionHijack). - // If this fails we'll use the same method as on X86, even though the - // stack will become un-walkable + IDacDbiInterface::TargetInfo targetInfo; + GetProcess()->GetTargetInfo(&targetInfo); + if (targetInfo.arch != IDacDbiInterface::kArchX86) + { + // On X86 Debugger::GenericHijackFunc() ensures the stack is walkable + // by simply using the EBP chain, therefore we can execute the hijack + // by setting the thread's context EIP to point to this function. + // On X64, however, we first attempt to set up a "proper" hijack, with + // a function that allows the OS to unwind the stack (ExceptionHijack). + // If this fails we'll use the same method as on X86, even though the + // stack will become un-walkable - ULONG32 dwThreadId = GetOSTid(); - CordbThread * pThread = GetProcess()->TryLookupOrCreateThreadByVolatileOSId(dwThreadId); + ULONG32 dwThreadId = GetOSTid(); + CordbThread * pThread = GetProcess()->TryLookupOrCreateThreadByVolatileOSId(dwThreadId); - // For threads in the thread store we set up the full size - // hijack, otherwise we fallback to hijacking by SetIP. - if (pThread != NULL) - { - HRESULT hr = S_OK; - EX_TRY + // For threads in the thread store we set up the full size + // hijack, otherwise we fallback to hijacking by SetIP. + if (pThread != NULL) { - // Note that the data-target is not atomic, and we have no rollback mechanism. - // We have to do several writes. If the data-target fails the writes half-way through the - // target will be inconsistent. - IfFailThrow(GetProcess()->GetDAC()->Hijack( - pThread->m_vmThreadToken, - dwThreadId, - pRecord, - (T_CONTEXT*) GetHijackCtx(), - sizeof(T_CONTEXT), - EHijackReason::kGenericHijack, - NULL, - NULL)); - } - EX_CATCH_HRESULT(hr); - if (SUCCEEDED(hr)) - { - // Remember that we've hijacked the thread. - SetState(CUTS_GenericHijacked); + HRESULT hr = S_OK; + EX_TRY + { + // Note that the data-target is not atomic, and we have no rollback mechanism. + // We have to do several writes. If the data-target fails the writes half-way through the + // target will be inconsistent. + IfFailThrow(GetProcess()->GetDAC()->Hijack( + pThread->m_vmThreadToken, + dwThreadId, + pRecord, + (T_CONTEXT*) GetHijackCtx(), + sizeof(T_CONTEXT), + EHijackReason::kGenericHijack, + NULL, + NULL)); + } + EX_CATCH_HRESULT(hr); + if (SUCCEEDED(hr)) + { + // Remember that we've hijacked the thread. + SetState(CUTS_GenericHijacked); - return S_OK; - } + return S_OK; + } - STRESS_LOG1(LF_CORDB, LL_INFO1000, "CUT::SGH: Error setting up hijack context hr=0x%x\n", hr); - // fallthrough (above hijack might have failed due to stack overflow, for example) + STRESS_LOG1(LF_CORDB, LL_INFO1000, "CUT::SGH: Error setting up hijack context hr=0x%x\n", hr); + // fallthrough (above hijack might have failed due to stack overflow, for example) - } - // else (non-threadstore threads) fallthrough + } + // else (non-threadstore threads) fallthrough -#endif // TARGET_AMD64 || defined(TARGET_ARM64) + } // Remember that we've hijacked the thread. SetState(CUTS_GenericHijacked); @@ -4027,7 +4026,7 @@ void CordbUnmanagedThread::SetupForSkipBreakpoint(NativePatch * pNativePatch) fTrapOnSkip = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgTrapOnSkip); } #endif -#if defined(TARGET_X86) +#if defined(HOST_X86) STRESS_LOG2(LF_CORDB, LL_INFO100, "CUT::SetupSkip. addr=%p. Opcode=%x\n", pNativePatch->pAddress, (DWORD) pNativePatch->opcode); #endif @@ -4080,11 +4079,11 @@ void CordbUnmanagedThread::FixupForSkipBreakpoint() inline TADDR GetSP(DT_CONTEXT* context) { -#if defined(TARGET_X86) +#if defined(HOST_X86) return (TADDR)context->Esp; -#elif defined(TARGET_AMD64) +#elif defined(HOST_AMD64) return (TADDR)context->Rsp; -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) +#elif defined(HOST_ARM) || defined(HOST_ARM64) return (TADDR)context->Sp; #else _ASSERTE(!"nyi for platform"); @@ -4227,17 +4226,17 @@ void CordbUnmanagedThread::SaveRaiseExceptionEntryContext() // calculate the exception that we would expect to come from this invocation of RaiseException REMOTE_PTR pExceptionInformation = NULL; -#if defined(TARGET_AMD64) +#if defined(HOST_AMD64) m_raiseExceptionExceptionCode = (DWORD)m_raiseExceptionEntryContext.Rcx; m_raiseExceptionExceptionFlags = (DWORD)m_raiseExceptionEntryContext.Rdx; m_raiseExceptionNumberParameters = (DWORD)m_raiseExceptionEntryContext.R8; pExceptionInformation = (REMOTE_PTR)m_raiseExceptionEntryContext.R9; -#elif defined(TARGET_ARM64) +#elif defined(HOST_ARM64) m_raiseExceptionExceptionCode = (DWORD)m_raiseExceptionEntryContext.X0; m_raiseExceptionExceptionFlags = (DWORD)m_raiseExceptionEntryContext.X1; m_raiseExceptionNumberParameters = (DWORD)m_raiseExceptionEntryContext.X2; pExceptionInformation = (REMOTE_PTR)m_raiseExceptionEntryContext.X3; -#elif defined(TARGET_X86) +#elif defined(HOST_X86) hr = m_pProcess->SafeReadStruct(PTR_TO_CORDB_ADDRESS((BYTE*)m_raiseExceptionEntryContext.Esp+4), &m_raiseExceptionExceptionCode); if(FAILED(hr)) { @@ -4357,9 +4356,9 @@ BOOL CordbUnmanagedThread::IsExceptionFromLastRaiseException(const EXCEPTION_REC // This flavor is assuming our caller already knows the opcode. HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress) { -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(HOST_X86) || defined(HOST_AMD64) const BYTE patch = CORDbg_BREAK_INSTRUCTION; -#elif defined(TARGET_ARM64) +#elif defined(HOST_ARM64) const PRD_TYPE patch = CORDbg_BREAK_INSTRUCTION; #else const BYTE patch = 0; @@ -4374,10 +4373,10 @@ HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress) // Get the opcode that we're replacing. HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE * pOpcode) { -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(HOST_X86) || defined(HOST_AMD64) // Read out opcode. 1 byte on x86 BYTE opcode; -#elif defined(TARGET_ARM64) +#elif defined(HOST_ARM64) // Read out opcode. 4 bytes on arm64 PRD_TYPE opcode; #else @@ -4401,10 +4400,10 @@ HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, P //----------------------------------------------------------------------------- HRESULT RemoveRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE opcode) { -#if defined(TARGET_X86) || defined(TARGET_AMD64) +#if defined(HOST_X86) || defined(HOST_AMD64) // Replace the BP w/ the opcode. BYTE opcode2 = (BYTE) opcode; -#elif defined(TARGET_ARM64) +#elif defined(HOST_ARM64) // 4 bytes on arm64 PRD_TYPE opcode2 = opcode; #else @@ -4712,7 +4711,7 @@ HRESULT CordbFrame::CreateStepper(ICorDebugStepper **ppStepper) //--------------------------------------------------------------------------------------- // -// Given a frame pointer, determine if it is in the stack range owned by the frame. +// X86-specific helper: Given a frame pointer, determine if it is in the stack range owned by the frame. // // Arguments: // fp - frame pointer to check @@ -4733,7 +4732,6 @@ bool CordbFrame::IsContainedInFrame(FramePointer fp) CORDB_ADDRESS sp = PTR_TO_CORDB_ADDRESS(fp.GetSPValue()); -#if defined(TARGET_X86) // On x86, the runtime sends CallerSP - sizeof(TADDR) as the frame pointer // for exception notifications (see GetSpForDiagnosticReporting). Since this // does not account for the stack parameter size, we adjust for it here. @@ -4752,7 +4750,6 @@ bool CordbFrame::IsContainedInFrame(FramePointer fp) } } } -#endif // TARGET_X86 if ((stackStart <= sp) && (sp <= stackEnd)) { @@ -5937,13 +5934,18 @@ HRESULT CordbNativeFrame::GetStackParameterSize(ULONG32 * pSize) ThrowHR(E_INVALIDARG); } -#if defined(TARGET_X86) IDacDbiInterface * pDAC = GetProcess()->GetDAC(); - IfFailThrow(pDAC->GetStackParameterSize(PTR_TO_CORDB_ADDRESS(CORDbgGetIP(&m_context)), pSize)); -#else // !TARGET_X86 - hr = S_FALSE; - *pSize = 0; -#endif // TARGET_X86 + IDacDbiInterface::TargetInfo targetInfo; + IfFailThrow(GetProcess()->GetTargetInfo(&targetInfo)); + if (targetInfo.arch == IDacDbiInterface::kArchX86) + { + IfFailThrow(pDAC->GetStackParameterSize(PTR_TO_CORDB_ADDRESS(CORDbgGetIP(&m_context)), pSize)); + } + else + { + hr = S_FALSE; + *pSize = 0; + } } EX_CATCH_HRESULT(hr); @@ -6708,18 +6710,32 @@ HRESULT CordbNativeFrame::GetLocalRegisterValue(CorDebugRegister reg, VALIDATE_POINTER_TO_OBJECT(ppValue, ICorDebugValue **); ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess()); -#if defined(TARGET_X86) || defined(TARGET_64BIT) -#if defined(TARGET_X86) - if ((reg >= REGISTER_X86_FPSTACK_0) && (reg <= REGISTER_X86_FPSTACK_7)) -#elif defined(TARGET_AMD64) - if ((reg >= REGISTER_AMD64_XMM0) && (reg <= REGISTER_AMD64_XMM15)) -#elif defined(TARGET_ARM64) - if ((reg >= REGISTER_ARM64_V0) && (reg <= REGISTER_ARM64_V31)) -#endif + bool isFloatingPoint = false; + IDacDbiInterface::TargetInfo targetInfo; + IfFailThrow(GetProcess()->GetTargetInfo(&targetInfo)); + switch (targetInfo.arch) { - return GetLocalFloatingPointValue(reg, pType, ppValue); + case IDacDbiInterface::kArchX86: + isFloatingPoint = (reg >= REGISTER_X86_FPSTACK_0) && (reg <= REGISTER_X86_FPSTACK_7); + break; + case IDacDbiInterface::kArchAMD64: + isFloatingPoint = (reg >= REGISTER_AMD64_XMM0) && (reg <= REGISTER_AMD64_XMM15); + break; + case IDacDbiInterface::kArchArm64: + isFloatingPoint = (reg >= REGISTER_ARM64_V0) && (reg <= REGISTER_ARM64_V31); + break; + case IDacDbiInterface::kArchRiscV64: + isFloatingPoint = (reg >= REGISTER_RISCV64_F0) && (reg <= REGISTER_RISCV64_F31); + break; + case IDacDbiInterface::kArchLoongArch64: + isFloatingPoint = (reg >= REGISTER_LOONGARCH64_F0) && (reg <= REGISTER_LOONGARCH64_F31); + break; + default: + break; } -#endif + + if (isFloatingPoint) + return GetLocalFloatingPointValue(reg, pType, ppValue); // The address of the given register is the address of the value // in this process. We have no remote address here. @@ -6957,33 +6973,6 @@ HRESULT CordbNativeFrame::GetLocalFloatingPointValue(DWORD index, (et != ELEMENT_TYPE_R8)) return E_INVALIDARG; -#if defined(TARGET_AMD64) - if (!((index >= REGISTER_AMD64_XMM0) && - (index <= REGISTER_AMD64_XMM15))) - return E_INVALIDARG; - index -= REGISTER_AMD64_XMM0; -#elif defined(TARGET_ARM64) - if (!((index >= REGISTER_ARM64_V0) && - (index <= REGISTER_ARM64_V31))) - return E_INVALIDARG; - index -= REGISTER_ARM64_V0; -#elif defined(TARGET_ARM) - if (!((index >= REGISTER_ARM_D0) && - (index <= REGISTER_ARM_D31))) - return E_INVALIDARG; - index -= REGISTER_ARM_D0; -#elif defined(TARGET_RISCV64) - if (!((index >= REGISTER_RISCV64_F0) && - (index <= REGISTER_RISCV64_F31))) - return E_INVALIDARG; - index -= REGISTER_RISCV64_F0; -#else - if (!((index >= REGISTER_X86_FPSTACK_0) && - (index <= REGISTER_X86_FPSTACK_7))) - return E_INVALIDARG; - index -= REGISTER_X86_FPSTACK_0; -#endif - ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess()); @@ -7002,22 +6991,26 @@ HRESULT CordbNativeFrame::GetLocalFloatingPointValue(DWORD index, EX_CATCH_HRESULT(hr); if (SUCCEEDED(hr)) { -#if !defined(TARGET_64BIT) - // This is needed on x86 because we are dealing with a stack. - index = pThread->m_floatStackTop - index; -#endif + IDacDbiInterface::TargetInfo targetInfo; + GetProcess()->GetTargetInfo(&targetInfo); + if (targetInfo.arch == IDacDbiInterface::kArchX86) + { + // This is needed on x86 because we are dealing with a stack. + index = pThread->m_floatStackTop - index; + } if (index >= (sizeof(pThread->m_floatValues) / sizeof(pThread->m_floatValues[0]))) return E_INVALIDARG; -#ifdef TARGET_X86 - // A workaround (sort of) to get around the difference in format between - // a float value and a double value. We can't simply cast a double pointer to - // a float pointer. Instead, we have to cast the double itself to a float. - if (pType->m_elementType == ELEMENT_TYPE_R4) - *(float *)&(pThread->m_floatValues[index]) = (float)pThread->m_floatValues[index]; -#endif + if (targetInfo.arch == IDacDbiInterface::kArchX86) + { + // A workaround (sort of) to get around the difference in format between + // a float value and a double value. We can't simply cast a double pointer to + // a float pointer. Instead, we have to cast the double itself to a float. + if (pType->m_elementType == ELEMENT_TYPE_R4) + *(float *)&(pThread->m_floatValues[index]) = (float)pThread->m_floatValues[index]; + } ICorDebugValue* pValue; @@ -7366,12 +7359,17 @@ HRESULT CordbJITILFrame::Init() IfFailThrow(GetArgumentType(0, &pArgType)); ULONG32 argSize = 0; IfFailThrow(pArgType->GetUnboxedObjectSize(&argSize)); -#if defined(TARGET_X86) // (STACK_GROWS_DOWN_ON_ARGS_WALK) - m_FirstArgAddr = argBase - argSize; -#else // !TARGET_X86 (STACK_GROWS_UP_ON_ARGS_WALK) - AlignAddressForType(pArgType, argBase); - m_FirstArgAddr = argBase; -#endif // !TARGET_X86 (STACK_GROWS_UP_ON_ARGS_WALK) + IDacDbiInterface::TargetInfo targetInfo; + IfFailThrow(GetProcess()->GetTargetInfo(&targetInfo)); + if (targetInfo.arch == IDacDbiInterface::kArchX86) + { + m_FirstArgAddr = argBase - argSize; + } + else + { + AlignAddressForType(pArgType, argBase); + m_FirstArgAddr = argBase; + } } // The stackwalking code can't always successfully retrieve the generics type token. @@ -7999,21 +7997,8 @@ HRESULT CordbJITILFrame::FabricateNativeInfo(DWORD dwIndex, } else { - // We'll initialize everything at once - ULONG cbArchitectureMin; - - // m_FirstArgAddr will already be aligned on platforms that require alignment CORDB_ADDRESS rpCur = m_FirstArgAddr; -#if defined(TARGET_X86) || defined(TARGET_ARM) - cbArchitectureMin = 4; -#elif defined(TARGET_64BIT) - cbArchitectureMin = 8; -#else - cbArchitectureMin = 8; //REVISIT_TODO not sure if this is correct - PORTABILITY_ASSERT("What is the architecture-dependent minimum word size?"); -#endif // TARGET_X86 - // make a copy of the cached SigParser SigParser sigParser = m_sigParserCached; @@ -8031,13 +8016,16 @@ HRESULT CordbJITILFrame::FabricateNativeInfo(DWORD dwIndex, IfFailThrow(pArgType->GetUnboxedObjectSize(&cbType)); -#if defined(TARGET_X86) // STACK_GROWS_DOWN_ON_ARGS_WALK - // The rpCur pointer starts off in the right spot for the - // first argument, but thereafter we have to decrement it - // before getting the variable's location from it. So increment - // it here to be consistent later. - rpCur += max((ULONG)cbType, cbArchitectureMin); -#endif + IDacDbiInterface::TargetInfo targetInfo; + IfFailThrow(GetProcess()->GetTargetInfo(&targetInfo)); + if (targetInfo.arch == IDacDbiInterface::kArchX86) + { + // The rpCur pointer starts off in the right spot for the + // first argument, but thereafter we have to decrement it + // before getting the variable's location from it. So increment + // it here to be consistent later. + rpCur += max((ULONG)cbType, (ULONG)targetInfo.pointerSize); + } // Grab the IL code's function's method signature so we can see if it's static. BOOL fMethodIsStatic; @@ -8068,20 +8056,23 @@ HRESULT CordbJITILFrame::FabricateNativeInfo(DWORD dwIndex, IfFailThrow(pArgType->GetUnboxedObjectSize(&cbType)); -#if defined(TARGET_X86) // STACK_GROWS_DOWN_ON_ARGS_WALK - rpCur -= max((ULONG)cbType, cbArchitectureMin); - m_rgNVI[i].loc.vlFixedVarArg.vlfvOffset = - (unsigned)(m_FirstArgAddr - rpCur); - - // Since the JIT adds in the size of this field, we do too to - // be consistent. - m_rgNVI[i].loc.vlFixedVarArg.vlfvOffset += sizeof(((CORINFO_VarArgInfo*)0)->argBytes); -#else // STACK_GROWS_UP_ON_ARGS_WALK - m_rgNVI[i].loc.vlFixedVarArg.vlfvOffset = - (unsigned)(rpCur - m_FirstArgAddr); - rpCur += max((ULONG)cbType, cbArchitectureMin); - AlignAddressForType(pArgType, rpCur); -#endif + if (targetInfo.arch == IDacDbiInterface::kArchX86) + { + rpCur -= max((ULONG)cbType, (ULONG)targetInfo.pointerSize); + m_rgNVI[i].loc.vlFixedVarArg.vlfvOffset = + (unsigned)(m_FirstArgAddr - rpCur); + + // Since the JIT adds in the size of this field, we do too to + // be consistent. + m_rgNVI[i].loc.vlFixedVarArg.vlfvOffset += sizeof(((CORINFO_VarArgInfo*)0)->argBytes); + } + else + { + m_rgNVI[i].loc.vlFixedVarArg.vlfvOffset = + (unsigned)(rpCur - m_FirstArgAddr); + rpCur += max((ULONG)cbType, (ULONG)targetInfo.pointerSize); + AlignAddressForType(pArgType, rpCur); + } IfFailThrow(sigParser.SkipExactlyOne()); } // for ( ; i M m_allArgsCount; i++) @@ -8252,27 +8243,23 @@ HRESULT CordbJITILFrame::GetNativeVariable(CordbType *type, } break; -#if defined(TARGET_64BIT) || defined(TARGET_ARM) case ICorDebugInfo::VLT_REG_FP: -#if defined(TARGET_ARM) // @ARMTODO - hr = E_NOTIMPL; -#elif defined(TARGET_AMD64) - hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg + REGISTER_AMD64_XMM0, - type, ppValue); -#elif defined(TARGET_ARM64) - hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg + REGISTER_ARM64_V0, - type, ppValue); -#elif defined(TARGET_LOONGARCH64) - hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg + REGISTER_LOONGARCH64_F0, - type, ppValue); -#elif defined(TARGET_RISCV64) - hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg + REGISTER_RISCV64_F0, - type, ppValue); -#else -#error Platform not implemented -#endif // TARGET_ARM @ARMTODO + { + IDacDbiInterface::TargetInfo targetInfo; + IfFailThrow(GetProcess()->GetTargetInfo(&targetInfo)); + switch (targetInfo.arch) + { + case IDacDbiInterface::kArchArm64: + case IDacDbiInterface::kArchAMD64: + case IDacDbiInterface::kArchLoongArch64: + case IDacDbiInterface::kArchRiscV64: + hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg, type, ppValue); + break; + default: + break; + } + } break; -#endif // TARGET_64BIT || TARGET_ARM case ICorDebugInfo::VLT_STK_BYREF: { @@ -8338,9 +8325,6 @@ HRESULT CordbJITILFrame::GetNativeVariable(CordbType *type, break; case ICorDebugInfo::VLT_FPSTK: -#if defined(TARGET_ARM) // @ARMTODO - hr = E_NOTIMPL; -#else /* @TODO [Microsoft] We have to make this work!!!!!!!!!!!!! hr = m_nativeFrame->GetLocalFloatingPointValue( @@ -8348,7 +8332,6 @@ HRESULT CordbJITILFrame::GetNativeVariable(CordbType *type, type, ppValue); */ hr = CORDBG_E_IL_VAR_NOT_AVAILABLE; -#endif break; case ICorDebugInfo::VLT_FIXED_VA: @@ -8358,13 +8341,18 @@ HRESULT CordbJITILFrame::GetNativeVariable(CordbType *type, CORDB_ADDRESS pRemoteValue; -#if defined(TARGET_X86) // STACK_GROWS_DOWN_ON_ARGS_WALK - pRemoteValue = m_FirstArgAddr - pNativeVarInfo->loc.vlFixedVarArg.vlfvOffset; - // Remember to subtract out this amount - pRemoteValue += sizeof(((CORINFO_VarArgInfo*)0)->argBytes); -#else // STACK_GROWS_UP_ON_ARGS_WALK - pRemoteValue = m_FirstArgAddr + pNativeVarInfo->loc.vlFixedVarArg.vlfvOffset; -#endif + IDacDbiInterface::TargetInfo targetInfo; + IfFailThrow(GetProcess()->GetTargetInfo(&targetInfo)); + if (targetInfo.arch == IDacDbiInterface::kArchX86) + { + pRemoteValue = m_FirstArgAddr - pNativeVarInfo->loc.vlFixedVarArg.vlfvOffset; + // Remember to subtract out this amount + pRemoteValue += sizeof(((CORINFO_VarArgInfo*)0)->argBytes); + } + else + { + pRemoteValue = m_FirstArgAddr + pNativeVarInfo->loc.vlFixedVarArg.vlfvOffset; + } hr = m_nativeFrame->GetLocalMemoryValue(pRemoteValue, type, diff --git a/src/coreclr/debug/di/rstype.cpp b/src/coreclr/debug/di/rstype.cpp index c2021026a30f46..45b8c0de0ae03d 100644 --- a/src/coreclr/debug/di/rstype.cpp +++ b/src/coreclr/debug/di/rstype.cpp @@ -2659,7 +2659,6 @@ void CordbType::GatherTypeDataForInstantiation(unsigned int genericArgsCount, IC } } -#ifdef FEATURE_64BIT_ALIGNMENT // checks if the type requires 8-byte alignment. the algorithm used here // was adapted from AdjustArgPtrForAlignment() in bcltype/VarArgsNative.cpp HRESULT CordbType::RequiresAlign8(BOOL* isRequired) @@ -2703,7 +2702,6 @@ HRESULT CordbType::RequiresAlign8(BOOL* isRequired) return hr; } -#endif /* ------------------------------------------------------------------------- * * TypeParameter Enumerator class diff --git a/src/coreclr/debug/di/shimdatatarget.h b/src/coreclr/debug/di/shimdatatarget.h index c2e92c217dd6c1..32f2eeadd9d398 100644 --- a/src/coreclr/debug/di/shimdatatarget.h +++ b/src/coreclr/debug/di/shimdatatarget.h @@ -15,6 +15,7 @@ // Function to invoke for typedef HRESULT (*FPContinueStatusChanged)(void * pUserData, DWORD dwThreadId, CORDB_CONTINUE_STATUS dwContinueStatus); +class ShimProcess; //--------------------------------------------------------------------------------------- // Data target for a live process. This is used by Shim. @@ -27,6 +28,9 @@ class ShimDataTarget : public ICorDebugMutableDataTarget, ICorDebugDataTarget4 // Allow hooking an implementation for ContinueStatusChanged. void HookContinueStatusChanged(FPContinueStatusChanged fpContinueStatusChanged, void * pUserData); + void SetShimProcess(ShimProcess * pShim) { m_pShim = pShim; } + ShimProcess * GetShimProcess() { return m_pShim; } + // Release any resources. Also called by destructor. virtual void Dispose() = 0; @@ -102,6 +106,8 @@ class ShimDataTarget : public ICorDebugMutableDataTarget, ICorDebugDataTarget4 FPContinueStatusChanged m_fpContinueStatusChanged; void * m_pContinueStatusChangedUserData; + ShimProcess * m_pShim = NULL; + // Reference count. LONG m_ref; }; diff --git a/src/coreclr/debug/di/shimlocaldatatarget.cpp b/src/coreclr/debug/di/shimlocaldatatarget.cpp index 8bad40ee735e29..88a7b0f65f2f67 100644 --- a/src/coreclr/debug/di/shimlocaldatatarget.cpp +++ b/src/coreclr/debug/di/shimlocaldatatarget.cpp @@ -81,7 +81,7 @@ class ShimLocalDataTarget : public ShimDataTarget // Note: throws BOOL CompatibleHostAndTargetPlatforms(HANDLE hTargetProcess) { -#if defined(TARGET_UNIX) +#if defined(HOST_UNIX) return TRUE; #else // get the platform for the host process @@ -278,17 +278,17 @@ HRESULT STDMETHODCALLTYPE ShimLocalDataTarget::GetPlatform( CorDebugPlatform *pPlatform) { -#ifdef TARGET_UNIX +#ifdef HOST_UNIX #error ShimLocalDataTarget is not implemented on PAL systems yet #endif // Assume that we're running on Windows for now. -#if defined(TARGET_X86) +#if defined(HOST_X86) *pPlatform = CORDB_PLATFORM_WINDOWS_X86; -#elif defined(TARGET_AMD64) +#elif defined(HOST_AMD64) *pPlatform = CORDB_PLATFORM_WINDOWS_AMD64; -#elif defined(TARGET_ARM) +#elif defined(HOST_ARM) *pPlatform = CORDB_PLATFORM_WINDOWS_ARM; -#elif defined(TARGET_ARM64) +#elif defined(HOST_ARM64) *pPlatform = CORDB_PLATFORM_WINDOWS_ARM64; #else #error Unknown Processor. @@ -462,9 +462,6 @@ ShimLocalDataTarget::ContinueStatusChanged( HRESULT STDMETHODCALLTYPE ShimLocalDataTarget::VirtualUnwind(DWORD threadId, ULONG32 contextSize, PBYTE context) { -#ifndef TARGET_UNIX - _ASSERTE(!"ShimLocalDataTarget::VirtualUnwind NOT IMPLEMENTED"); -#endif return E_NOTIMPL; } diff --git a/src/coreclr/debug/di/shimpriv.h b/src/coreclr/debug/di/shimpriv.h index acbf2b5da4b522..4c575e480a9a8f 100644 --- a/src/coreclr/debug/di/shimpriv.h +++ b/src/coreclr/debug/di/shimpriv.h @@ -20,6 +20,7 @@ // Forward declarations class CordbWin32EventThread; class Cordb; +struct IDacDbiInterface; class ShimStackWalk; class ShimChain; @@ -1046,4 +1047,3 @@ class ShimFrameEnum : public ICorDebugFrameEnum #endif // SHIMPRIV_H - diff --git a/src/coreclr/debug/di/shimprocess.cpp b/src/coreclr/debug/di/shimprocess.cpp index 363cd07f926ff1..3992cc5a5b5825 100644 --- a/src/coreclr/debug/di/shimprocess.cpp +++ b/src/coreclr/debug/di/shimprocess.cpp @@ -159,6 +159,7 @@ HRESULT ShimProcess::InitializeDataTarget(const ProcessDescriptor * pProcessDesc return hr; } m_pLiveDataTarget->HookContinueStatusChanged(ShimProcess::ContinueStatusChanged, this); + m_pLiveDataTarget->SetShimProcess(this); // Ref on pDataTarget is now 1. _ASSERTE(m_pLiveDataTarget != NULL); diff --git a/src/coreclr/debug/di/shimremotedatatarget.cpp b/src/coreclr/debug/di/shimremotedatatarget.cpp index de3413e1c7fc1b..e14b5b6d66e344 100644 --- a/src/coreclr/debug/di/shimremotedatatarget.cpp +++ b/src/coreclr/debug/di/shimremotedatatarget.cpp @@ -246,39 +246,45 @@ HRESULT STDMETHODCALLTYPE ShimRemoteDataTarget::GetPlatform( CorDebugPlatform *pPlatform) { -#ifdef TARGET_UNIX - #if defined(TARGET_X86) - *pPlatform = CORDB_PLATFORM_POSIX_X86; - #elif defined(TARGET_AMD64) - *pPlatform = CORDB_PLATFORM_POSIX_AMD64; - #elif defined(TARGET_ARM) - *pPlatform = CORDB_PLATFORM_POSIX_ARM; - #elif defined(TARGET_ARM64) - *pPlatform = CORDB_PLATFORM_POSIX_ARM64; - #elif defined(TARGET_LOONGARCH64) - *pPlatform = CORDB_PLATFORM_POSIX_LOONGARCH64; - #elif defined(TARGET_RISCV64) - *pPlatform = CORDB_PLATFORM_POSIX_RISCV64; - #else - #error Unknown Processor. - #endif -#else - #if defined(TARGET_X86) - *pPlatform = CORDB_PLATFORM_WINDOWS_X86; - #elif defined(TARGET_AMD64) - *pPlatform = CORDB_PLATFORM_WINDOWS_AMD64; - #elif defined(TARGET_ARM) - *pPlatform = CORDB_PLATFORM_WINDOWS_ARM; - #elif defined(TARGET_ARM64) - *pPlatform = CORDB_PLATFORM_WINDOWS_ARM64; - #elif defined(TARGET_LOONGARCH64) - *pPlatform = CORDB_PLATFORM_WINDOWS_LOONGARCH64; - #else - #error Unknown Processor. - #endif -#endif + ShimProcess * pShim = GetShimProcess(); + if (pShim != NULL) + { + CordbProcess * pProcess = static_cast(pShim->GetProcess()); + if (pProcess != NULL) + { + IDacDbiInterface::TargetInfo targetInfo; + if (SUCCEEDED(pProcess->GetTargetInfo(&targetInfo))) + { + if (targetInfo.os == IDacDbiInterface::kOSWindows) + { + switch (targetInfo.arch) + { + case IDacDbiInterface::kArchX86: *pPlatform = CORDB_PLATFORM_WINDOWS_X86; return S_OK; + case IDacDbiInterface::kArchAMD64: *pPlatform = CORDB_PLATFORM_WINDOWS_AMD64; return S_OK; + case IDacDbiInterface::kArchArm: *pPlatform = CORDB_PLATFORM_WINDOWS_ARM; return S_OK; + case IDacDbiInterface::kArchArm64: *pPlatform = CORDB_PLATFORM_WINDOWS_ARM64; return S_OK; + default: break; + } + } + else if (targetInfo.os == IDacDbiInterface::kOSUnix) + { + switch (targetInfo.arch) + { + case IDacDbiInterface::kArchX86: *pPlatform = CORDB_PLATFORM_POSIX_X86; return S_OK; + case IDacDbiInterface::kArchAMD64: *pPlatform = CORDB_PLATFORM_POSIX_AMD64; return S_OK; + case IDacDbiInterface::kArchArm: *pPlatform = CORDB_PLATFORM_POSIX_ARM; return S_OK; + case IDacDbiInterface::kArchArm64: *pPlatform = CORDB_PLATFORM_POSIX_ARM64; return S_OK; + case IDacDbiInterface::kArchLoongArch64: *pPlatform = CORDB_PLATFORM_POSIX_LOONGARCH64; return S_OK; + case IDacDbiInterface::kArchRiscV64: *pPlatform = CORDB_PLATFORM_POSIX_RISCV64; return S_OK; + default: break; + } + } + return S_OK; + } + } + } - return S_OK; + return E_FAIL; } // impl of interface method ICorDebugDataTarget::ReadVirtual @@ -340,7 +346,7 @@ ShimRemoteDataTarget::ReadVirtual( // pread on /proc//mem treats the offset as a file position, not a virtual address, // so the kernel does not apply TBI -- tagged pointers cause EINVAL. // See https://www.kernel.org/doc/html/latest/arch/arm64/tagged-address-abi.html -#ifdef TARGET_ARM64 +#ifdef HOST_ARM64 address &= 0x00FFFFFFFFFFFFFFULL; #endif ssize_t r = pread((int)m_memoryHandle, pBuffer, cbRequestSize, (off_t)address); diff --git a/src/coreclr/debug/di/shimstackwalk.cpp b/src/coreclr/debug/di/shimstackwalk.cpp index f289788507a54e..bd8a6310c09900 100644 --- a/src/coreclr/debug/di/shimstackwalk.cpp +++ b/src/coreclr/debug/di/shimstackwalk.cpp @@ -14,14 +14,6 @@ #include "stdafx.h" #include "primitives.h" -#if defined(TARGET_X86) -static const ULONG32 REGISTER_X86_MAX = REGISTER_X86_FPSTACK_7 + 1; -static const ULONG32 MAX_MASK_COUNT = (REGISTER_X86_MAX + 7) >> 3; -#elif defined(TARGET_AMD64) -static const ULONG32 REGISTER_AMD64_MAX = REGISTER_AMD64_XMM15 + 1; -static const ULONG32 MAX_MASK_COUNT = (REGISTER_AMD64_MAX + 7) >> 3; -#endif - ShimStackWalk::ShimStackWalk(ShimProcess * pProcess, ICorDebugThread * pThread) : m_pChainEnumList(NULL), m_pFrameEnumList(NULL) @@ -1119,12 +1111,18 @@ void ShimStackWalk::AppendChain(ChainInfo * pChainInfo, StackWalkInfo * pStackWa // We need to send an extra enter-managed chain. _ASSERTE(pChainInfo->m_fLeafNativeContextIsValid); BYTE * sp = reinterpret_cast(CORDB_ADDRESS_TO_PTR(CORDbgGetSP(&(pChainInfo->m_leafNativeContext)))); -#if !defined(TARGET_ARM) && !defined(TARGET_ARM64) + IDacDbiInterface::TargetInfo targetInfo; // Dev11 324806: on ARM we use the caller's SP for a frame's ending delimiter so we cannot - // subtract 4 bytes from the chain's ending delimiter else the frame might never be in range. + // subtract from the chain's ending delimiter else the frame might never be in range. // TODO: revisit overlapping ranges on ARM, it would be nice to make it consistent with the other architectures. - sp -= sizeof(LPVOID); -#endif + CordbProcess * pProcess = static_cast(m_pProcess->GetProcess()); + if (pProcess != NULL && + SUCCEEDED(pProcess->GetTargetInfo(&targetInfo)) && + targetInfo.arch != IDacDbiInterface::kArchArm && + targetInfo.arch != IDacDbiInterface::kArchArm64) + { + sp -= targetInfo.pointerSize; + } FramePointer fp = FramePointer::MakeFramePointer(sp); AppendChainWorker(pStackWalkInfo, diff --git a/src/coreclr/debug/di/valuehome.cpp b/src/coreclr/debug/di/valuehome.cpp index 1317df02b810a4..3fbb8bb5ee51bb 100644 --- a/src/coreclr/debug/di/valuehome.cpp +++ b/src/coreclr/debug/di/valuehome.cpp @@ -190,6 +190,7 @@ void RegValueHome::SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pCont // If the value is in a reg, then it's going to be a register's width (regardless of // the actual width of the data). // For signed types, like i2, i1, make sure we sign extend. + IDacDbiInterface::TargetInfo targetInfo; if (fIsSigned) { @@ -203,10 +204,13 @@ void RegValueHome::SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pCont extendedVal = (SSIZE_T) *(short*)newValue.StartAddress(); break; case 4: _ASSERTE(sizeof(DWORD) == 4); extendedVal = (SSIZE_T) *(int*)newValue.StartAddress(); break; -#if defined(TARGET_64BIT) - case 8: _ASSERTE(sizeof(ULONGLONG) == 8); - extendedVal = (SSIZE_T) *(ULONGLONG*)newValue.StartAddress(); break; -#endif // TARGET_64BIT + case 8: + { + IfFailThrow(m_pFrame->GetProcess()->GetTargetInfo(&targetInfo)); + _ASSERTE(targetInfo.pointerSize == 8); + extendedVal = (SSIZE_T) *(INT64*)newValue.StartAddress(); + break; + } default: _ASSERTE(!"bad size"); } } @@ -221,10 +225,13 @@ void RegValueHome::SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pCont extendedVal = *( WORD*)newValue.StartAddress(); break; case 4: _ASSERTE(sizeof(DWORD) == 4); extendedVal = *(DWORD*)newValue.StartAddress(); break; -#if defined(TARGET_64BIT) - case 8: _ASSERTE(sizeof(ULONGLONG) == 8); - extendedVal = *(ULONGLONG*)newValue.StartAddress(); break; -#endif // TARGET_64BIT + case 8: + { + IfFailThrow(m_pFrame->GetProcess()->GetTargetInfo(&targetInfo)); + _ASSERTE(targetInfo.pointerSize == 8); + extendedVal = *(UINT64*)newValue.StartAddress(); + break; + } default: _ASSERTE(!"bad size"); } } @@ -836,21 +843,9 @@ void RegisterValueHome::SetEnregisteredValue(MemoryRange src, bool fIsSigned) } // RegisterValueHome::SetEnregisteredValue -// Get an enregistered value from the register display of the native frame -// Arguments: -// output: dest - buffer will hold the register value -// Note: Throws E_NOTIMPL for attempts to get an enregistered value for a float register -// or for 64-bit platforms void RegisterValueHome::GetEnregisteredValue(MemoryRange dest) { -#if !defined(TARGET_X86) - _ASSERTE(!"@TODO IA64/AMD64 -- Not Yet Implemented"); ThrowHR(E_NOTIMPL); -#else // TARGET_X86 - _ASSERTE(m_pRemoteRegAddr != NULL); - - m_pRemoteRegAddr->GetEnregisteredValue(dest); // throws -#endif // !TARGET_X86 } // RegisterValueHome::GetEnregisteredValue // Is this a signed type or unsigned type? diff --git a/src/coreclr/debug/inc/dacdbiinterface.h b/src/coreclr/debug/inc/dacdbiinterface.h index 3c04bbe546e956..e1e53636d19781 100644 --- a/src/coreclr/debug/inc/dacdbiinterface.h +++ b/src/coreclr/debug/inc/dacdbiinterface.h @@ -2226,9 +2226,10 @@ IDacDbiInterface : public IUnknown { TargetArchitecture arch; TargetOperatingSystem os; + ULONG32 pointerSize; }; - // Returns the target's processor architecture and OS family. + // Returns the target's processor architecture, OS family, and pointer size. virtual HRESULT STDMETHODCALLTYPE GetTargetInfo(OUT TargetInfo * pTargetInfo) = 0; // The following tag tells the DD-marshalling tool to stop scanning. diff --git a/src/coreclr/inc/dacdbi.idl b/src/coreclr/inc/dacdbi.idl index e044556bb19ebb..da050a7dcc65d7 100644 --- a/src/coreclr/inc/dacdbi.idl +++ b/src/coreclr/inc/dacdbi.idl @@ -129,7 +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; +typedef struct { int arch; int os; int pointerSize; } TargetInfo; cpp_quote("#endif") From 59789b0968b6467ae5a6ce195e7145ab5e0e86eb Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 16 Jul 2026 17:24:57 -0700 Subject: [PATCH 03/26] copilot comments --- src/coreclr/debug/di/rspriv.h | 2 +- src/coreclr/debug/di/rsthread.cpp | 6 +++--- src/coreclr/debug/di/shimremotedatatarget.cpp | 2 +- .../Dbi/DacDbiImpl.cs | 3 +++ .../Dbi/IDacDbiInterface.cs | 1 + 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index 967091f622932e..c2221f45fd19e9 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -11391,7 +11391,7 @@ inline void AlignAddressForType(CordbType* pArgType, CORDB_ADDRESS& argBase) { #ifdef FEATURE_64BIT_ALIGNMENT BOOL align = FALSE; - HRESULT hr = pArgType->RequiresAlign8(&align); + IfFailThrow(pArgType->RequiresAlign8(&align)); if (align) argBase = ALIGN_ADDRESS(argBase, 8); diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index 4b50b5015fe233..ea6d0655c826aa 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -1394,7 +1394,7 @@ HRESULT CordbThread::FindFrame(ICorDebugFrame ** ppFrame, FramePointer fp) CordbFrame * pCFrame = CordbFrame::GetCordbFrameFromInterface(pIFrame); IDacDbiInterface::TargetInfo targetInfo; - GetProcess()->GetTargetInfo(&targetInfo); + IfFailRet(GetProcess()->GetTargetInfo(&targetInfo)); bool frameMatches = targetInfo.arch == IDacDbiInterface::kArchX86 ? pCFrame->IsContainedInFrame(fp) : pCFrame->GetFramePointer() == fp; if (frameMatches) { @@ -3812,7 +3812,7 @@ HRESULT CordbUnmanagedThread::SetupGenericHijack(DWORD eventCode, const EXCEPTIO } IDacDbiInterface::TargetInfo targetInfo; - GetProcess()->GetTargetInfo(&targetInfo); + IfFailRet(GetProcess()->GetTargetInfo(&targetInfo)); if (targetInfo.arch != IDacDbiInterface::kArchX86) { // On X86 Debugger::GenericHijackFunc() ensures the stack is walkable @@ -6993,7 +6993,7 @@ HRESULT CordbNativeFrame::GetLocalFloatingPointValue(DWORD index, if (SUCCEEDED(hr)) { IDacDbiInterface::TargetInfo targetInfo; - GetProcess()->GetTargetInfo(&targetInfo); + IfFailRet(GetProcess()->GetTargetInfo(&targetInfo)); if (targetInfo.arch == IDacDbiInterface::kArchX86) { // This is needed on x86 because we are dealing with a stack. diff --git a/src/coreclr/debug/di/shimremotedatatarget.cpp b/src/coreclr/debug/di/shimremotedatatarget.cpp index e14b5b6d66e344..0d08df8624142b 100644 --- a/src/coreclr/debug/di/shimremotedatatarget.cpp +++ b/src/coreclr/debug/di/shimremotedatatarget.cpp @@ -279,7 +279,7 @@ ShimRemoteDataTarget::GetPlatform( default: break; } } - return S_OK; + return CORDBG_E_UNSUPPORTED; } } } 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 cfaae58f463bfd..622d88cfb68f72 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 @@ -5781,6 +5781,8 @@ public int GetTargetInfo(TargetInfo* pTargetInfo) Contracts.RuntimeInfoOperatingSystem.Apple => TargetOperatingSystem.Unix, _ => TargetOperatingSystem.Unknown, }; + + pTargetInfo->PointerSize = (uint)_target.PointerSize; } catch (System.Exception ex) { @@ -5796,6 +5798,7 @@ public int GetTargetInfo(TargetInfo* pTargetInfo) { Debug.Assert(pTargetInfo->Arch == targetInfoLocal.Arch, $"cDAC: {pTargetInfo->Arch}, DAC: {targetInfoLocal.Arch}"); Debug.Assert(pTargetInfo->OS == targetInfoLocal.OS, $"cDAC: {pTargetInfo->OS}, DAC: {targetInfoLocal.OS}"); + Debug.Assert(pTargetInfo->PointerSize == targetInfoLocal.PointerSize, $"cDAC: {pTargetInfo->PointerSize}, DAC: {targetInfoLocal.PointerSize}"); } } #endif 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 9b2502868543e9..04fc77b3ae8c52 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 @@ -910,4 +910,5 @@ public struct TargetInfo { public TargetArchitecture Arch; public TargetOperatingSystem OS; + public uint PointerSize; } From 8de4d55d18c57ce39e6b957e917c36ef48881470 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 16 Jul 2026 17:42:59 -0700 Subject: [PATCH 04/26] fix --- src/coreclr/debug/di/rsthread.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index ea6d0655c826aa..efed850adfd364 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -6710,6 +6710,7 @@ HRESULT CordbNativeFrame::GetLocalRegisterValue(CorDebugRegister reg, VALIDATE_POINTER_TO_OBJECT(ppValue, ICorDebugValue **); ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess()); + DWORD floatingPointIndex = 0; bool isFloatingPoint = false; IDacDbiInterface::TargetInfo targetInfo; IfFailThrow(GetProcess()->GetTargetInfo(&targetInfo)); @@ -6717,25 +6718,34 @@ HRESULT CordbNativeFrame::GetLocalRegisterValue(CorDebugRegister reg, { case IDacDbiInterface::kArchX86: isFloatingPoint = (reg >= REGISTER_X86_FPSTACK_0) && (reg <= REGISTER_X86_FPSTACK_7); + floatingPointIndex = reg - REGISTER_X86_FPSTACK_0; break; case IDacDbiInterface::kArchAMD64: isFloatingPoint = (reg >= REGISTER_AMD64_XMM0) && (reg <= REGISTER_AMD64_XMM15); + floatingPointIndex = reg - REGISTER_AMD64_XMM0; + break; + case IDacDbiInterface::kArchArm: + isFloatingPoint = (reg >= REGISTER_ARM_D0) && (reg <= REGISTER_ARM_D31); + floatingPointIndex = reg - REGISTER_ARM_D0; break; case IDacDbiInterface::kArchArm64: isFloatingPoint = (reg >= REGISTER_ARM64_V0) && (reg <= REGISTER_ARM64_V31); + floatingPointIndex = reg - REGISTER_ARM64_V0; break; case IDacDbiInterface::kArchRiscV64: isFloatingPoint = (reg >= REGISTER_RISCV64_F0) && (reg <= REGISTER_RISCV64_F31); + floatingPointIndex = reg - REGISTER_RISCV64_F0; break; case IDacDbiInterface::kArchLoongArch64: isFloatingPoint = (reg >= REGISTER_LOONGARCH64_F0) && (reg <= REGISTER_LOONGARCH64_F31); + floatingPointIndex = reg - REGISTER_LOONGARCH64_F0; break; default: break; } if (isFloatingPoint) - return GetLocalFloatingPointValue(reg, pType, ppValue); + return GetLocalFloatingPointValue(floatingPointIndex, pType, ppValue); // The address of the given register is the address of the value // in this process. We have no remote address here. From 356609aab0da9d4250738889a1d24a34934c12a1 Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Thu, 16 Jul 2026 17:45:13 -0700 Subject: [PATCH 05/26] Update dacdbi.idl --- src/coreclr/inc/dacdbi.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/inc/dacdbi.idl b/src/coreclr/inc/dacdbi.idl index 642dfdbfc5041d..edf90a12340046 100644 --- a/src/coreclr/inc/dacdbi.idl +++ b/src/coreclr/inc/dacdbi.idl @@ -129,7 +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; int pointerSize; } TargetInfo; +typedef struct { int arch; int os; uint pointerSize; } TargetInfo; cpp_quote("#endif") From 5ceacc002fc5074b996ebd85ced561b0c0c9347d Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Thu, 16 Jul 2026 19:12:57 -0700 Subject: [PATCH 06/26] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../Dbi/IDacDbiInterface.cs | 1 + 1 file changed, 1 insertion(+) 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 04fc77b3ae8c52..e9c9ed2e8422bc 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 @@ -906,6 +906,7 @@ public enum TargetOperatingSystem Unix, } +[StructLayout(LayoutKind.Sequential)] public struct TargetInfo { public TargetArchitecture Arch; From 81d1b61bf7afe74c6fa86d653e164dac2b0716ed Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 16 Jul 2026 19:12:18 -0700 Subject: [PATCH 07/26] fix --- src/coreclr/debug/di/rsthread.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index efed850adfd364..d0546df3d7735e 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -1394,7 +1394,9 @@ HRESULT CordbThread::FindFrame(ICorDebugFrame ** ppFrame, FramePointer fp) CordbFrame * pCFrame = CordbFrame::GetCordbFrameFromInterface(pIFrame); IDacDbiInterface::TargetInfo targetInfo; - IfFailRet(GetProcess()->GetTargetInfo(&targetInfo)); + HRESULT hr = GetProcess()->GetTargetInfo(&targetInfo); + if (FAILED(hr)) + return hr; bool frameMatches = targetInfo.arch == IDacDbiInterface::kArchX86 ? pCFrame->IsContainedInFrame(fp) : pCFrame->GetFramePointer() == fp; if (frameMatches) { @@ -3812,7 +3814,9 @@ HRESULT CordbUnmanagedThread::SetupGenericHijack(DWORD eventCode, const EXCEPTIO } IDacDbiInterface::TargetInfo targetInfo; - IfFailRet(GetProcess()->GetTargetInfo(&targetInfo)); + HRESULT hr = GetProcess()->GetTargetInfo(&targetInfo); + if (FAILED(hr)) + return hr; if (targetInfo.arch != IDacDbiInterface::kArchX86) { // On X86 Debugger::GenericHijackFunc() ensures the stack is walkable @@ -8366,11 +8370,16 @@ HRESULT CordbJITILFrame::GetNativeVariable(CordbType *type, hr = E_NOTIMPL; break; case IDacDbiInterface::kArchArm64: - case IDacDbiInterface::kArchAMD64: case IDacDbiInterface::kArchLoongArch64: case IDacDbiInterface::kArchRiscV64: hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg, type, ppValue); break; + case IDacDbiInterface::kArchAMD64: + hr = m_nativeFrame->GetLocalFloatingPointValue( + pNativeVarInfo->loc.vlReg.vlrReg - ICorDebugInfo::REGNUM_FP_FIRST, + type, + ppValue); + break; default: hr = CORDBG_E_IL_VAR_NOT_AVAILABLE; break; From fc1e282a81090b764db4235c7dc0f51e86301560 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 16 Jul 2026 20:17:04 -0700 Subject: [PATCH 08/26] fix --- src/coreclr/debug/di/rsthread.cpp | 2 +- src/coreclr/inc/dacdbi.idl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index d0546df3d7735e..0891ef1fbee4e7 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -8376,7 +8376,7 @@ HRESULT CordbJITILFrame::GetNativeVariable(CordbType *type, break; case IDacDbiInterface::kArchAMD64: hr = m_nativeFrame->GetLocalFloatingPointValue( - pNativeVarInfo->loc.vlReg.vlrReg - ICorDebugInfo::REGNUM_FP_FIRST, + ConvertRegNumToCorDebugRegister(pNativeVarInfo->loc.vlReg.vlrReg) - REGISTER_AMD64_XMM0, type, ppValue); break; diff --git a/src/coreclr/inc/dacdbi.idl b/src/coreclr/inc/dacdbi.idl index edf90a12340046..d23d76d7133f19 100644 --- a/src/coreclr/inc/dacdbi.idl +++ b/src/coreclr/inc/dacdbi.idl @@ -129,7 +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; uint pointerSize; } TargetInfo; +typedef struct { int arch; int os; ULONG32 pointerSize; } TargetInfo; cpp_quote("#endif") From c6095c0ae6793b5793fbbedbb236ddb36a7382e3 Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Thu, 16 Jul 2026 23:46:57 -0700 Subject: [PATCH 09/26] Update platformspecific.cpp --- src/coreclr/debug/di/platformspecific.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/coreclr/debug/di/platformspecific.cpp b/src/coreclr/debug/di/platformspecific.cpp index e26cacb7b149df..cd690dccc2fd25 100644 --- a/src/coreclr/debug/di/platformspecific.cpp +++ b/src/coreclr/debug/di/platformspecific.cpp @@ -21,22 +21,22 @@ #include "localeventchannel.cpp" #endif -#if HOST_X86 +#if TARGET_X86 #include "i386/cordbregisterset.cpp" #include "i386/primitives.cpp" -#elif HOST_AMD64 +#elif TARGET_AMD64 #include "amd64/cordbregisterset.cpp" #include "amd64/primitives.cpp" -#elif HOST_ARM +#elif TARGET_ARM #include "arm/cordbregisterset.cpp" #include "arm/primitives.cpp" -#elif HOST_ARM64 +#elif TARGET_ARM64 #include "arm64/cordbregisterset.cpp" #include "arm64/primitives.cpp" -#elif HOST_LOONGARCH64 +#elif TARGET_LOONGARCH64 #include "loongarch64/cordbregisterset.cpp" #include "loongarch64/primitives.cpp" -#elif HOST_RISCV64 +#elif TARGET_RISCV64 #include "riscv64/cordbregisterset.cpp" #include "riscv64/primitives.cpp" #else From 01d018cf5418735ab0ba82328597b646bd93dfd7 Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Thu, 16 Jul 2026 23:53:05 -0700 Subject: [PATCH 10/26] Cast newValue.StartAddress to SIZE_T for pointer size --- src/coreclr/debug/di/valuehome.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/debug/di/valuehome.cpp b/src/coreclr/debug/di/valuehome.cpp index 1abd79ee78c7c5..f67d6ffebbc17b 100644 --- a/src/coreclr/debug/di/valuehome.cpp +++ b/src/coreclr/debug/di/valuehome.cpp @@ -229,7 +229,7 @@ void RegValueHome::SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pCont { IfFailThrow(m_pFrame->GetProcess()->GetTargetInfo(&targetInfo)); _ASSERTE(targetInfo.pointerSize == 8); - extendedVal = *(UINT64*)newValue.StartAddress(); + extendedVal = (SIZE_T) *(UINT64*)newValue.StartAddress(); break; } default: _ASSERTE(!"bad size"); From d649561faee76514083df36507e3606cb26930e1 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Fri, 17 Jul 2026 11:12:49 -0700 Subject: [PATCH 11/26] revert a couple things --- src/coreclr/debug/di/process.cpp | 8 ++++---- src/coreclr/debug/di/rsthread.cpp | 21 +++++++++++++-------- src/coreclr/debug/di/valuehome.cpp | 10 +++++++++- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 2ea24960a30b88..6fa76f234f681f 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -8425,10 +8425,10 @@ CordbProcess::SetUnmanagedBreakpointInternal(CORDB_ADDRESS address, ULONG32 bufs HRESULT hr = S_OK; NativePatch * p = NULL; -#if defined(HOST_X86) || defined(HOST_AMD64) +#if defined(TARGET_X86) || defined(TARGET_AMD64) const BYTE patch = CORDbg_BREAK_INSTRUCTION; BYTE opcode; -#elif defined(HOST_ARM64) +#elif defined(TARGET_ARM64) const PRD_TYPE patch = CORDbg_BREAK_INSTRUCTION; PRD_TYPE opcode; #else @@ -8467,10 +8467,10 @@ CordbProcess::SetUnmanagedBreakpointInternal(CORDB_ADDRESS address, ULONG32 bufs goto ErrExit; // It's all successful, so now update our out-params & internal bookkeaping. -#if defined(HOST_X86) || defined(HOST_AMD64) +#if defined(TARGET_X86) || defined(TARGET_AMD64) opcode = (BYTE)p->opcode; buffer[0] = opcode; -#elif defined(HOST_ARM64) +#elif defined(TARGET_ARM64) opcode = p->opcode; memcpy_s(buffer, bufsize, &opcode, sizeof(opcode)); #else diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index 0891ef1fbee4e7..ddde51692b5b18 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -1388,15 +1388,16 @@ HRESULT CordbThread::FindFrame(ICorDebugFrame ** ppFrame, FramePointer fp) PRIVATE_SHIM_CALLBACK_IN_THIS_SCOPE0(GetProcess()); ShimStackWalk * pSSW = GetProcess()->GetShim()->LookupOrCreateShimStackWalk(this); + IDacDbiInterface::TargetInfo targetInfo; + HRESULT hr = GetProcess()->GetTargetInfo(&targetInfo); + if (FAILED(hr)) + return hr; + for (UINT32 i = 0; i < pSSW->GetFrameCount(); i++) { ICorDebugFrame * pIFrame = pSSW->GetFrame(i); CordbFrame * pCFrame = CordbFrame::GetCordbFrameFromInterface(pIFrame); - IDacDbiInterface::TargetInfo targetInfo; - HRESULT hr = GetProcess()->GetTargetInfo(&targetInfo); - if (FAILED(hr)) - return hr; bool frameMatches = targetInfo.arch == IDacDbiInterface::kArchX86 ? pCFrame->IsContainedInFrame(fp) : pCFrame->GetFramePointer() == fp; if (frameMatches) { @@ -4083,11 +4084,11 @@ void CordbUnmanagedThread::FixupForSkipBreakpoint() inline TADDR GetSP(DT_CONTEXT* context) { -#if defined(HOST_X86) +#if defined(TARGET_X86) return (TADDR)context->Esp; -#elif defined(HOST_AMD64) +#elif defined(TARGET_AMD64) return (TADDR)context->Rsp; -#elif defined(HOST_ARM) || defined(HOST_ARM64) +#elif defined(TARGET_ARM) || defined(TARGET_ARM64) return (TADDR)context->Sp; #else _ASSERTE(!"nyi for platform"); @@ -6717,7 +6718,11 @@ HRESULT CordbNativeFrame::GetLocalRegisterValue(CorDebugRegister reg, DWORD floatingPointIndex = 0; bool isFloatingPoint = false; IDacDbiInterface::TargetInfo targetInfo; - IfFailThrow(GetProcess()->GetTargetInfo(&targetInfo)); + HRESULT hr = GetProcess()->GetTargetInfo(&targetInfo); + if (FAILED(hr)) + { + return hr; + } switch (targetInfo.arch) { case IDacDbiInterface::kArchX86: diff --git a/src/coreclr/debug/di/valuehome.cpp b/src/coreclr/debug/di/valuehome.cpp index f67d6ffebbc17b..d82379a0f4085f 100644 --- a/src/coreclr/debug/di/valuehome.cpp +++ b/src/coreclr/debug/di/valuehome.cpp @@ -898,7 +898,15 @@ void RegisterValueHome::SetEnregisteredValue(MemoryRange src, bool fIsSigned) void RegisterValueHome::GetEnregisteredValue(MemoryRange dest) { - ThrowHR(E_NOTIMPL); + IfFailThrow(m_pFrame->GetProcess()->GetTargetInfo(&targetInfo)); + if (targetInfo.arch != kArchX86) + { + _ASSERTE(!"@TODO IA64/AMD64 -- Not Yet Implemented"); + ThrowHR(E_NOTIMPL); + } + _ASSERTE(m_pRemoteRegAddr != NULL); + + m_pRemoteRegAddr->GetEnregisteredValue(dest); // throws } // RegisterValueHome::GetEnregisteredValue // Is this a signed type or unsigned type? From af492d07cbff12dbdfee376e253ff3f72815e924 Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Fri, 17 Jul 2026 11:37:14 -0700 Subject: [PATCH 12/26] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../Dbi/DacDbiImpl.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 622d88cfb68f72..7823b6867d64b5 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 @@ -5758,8 +5758,7 @@ public int GetTargetInfo(TargetInfo* pTargetInfo) try { if (pTargetInfo is null) - throw new ArgumentNullException(nameof(pTargetInfo)); - + throw new ArgumentException("Output pointer cannot be null.", nameof(pTargetInfo)); Contracts.IRuntimeInfo runtimeInfo = _target.Contracts.RuntimeInfo; pTargetInfo->Arch = runtimeInfo.GetTargetArchitecture() switch From c9be9d1f110aabbe8a1b581392c5c5e787bf622d Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Fri, 17 Jul 2026 11:38:25 -0700 Subject: [PATCH 13/26] Update valuehome.cpp --- src/coreclr/debug/di/valuehome.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/debug/di/valuehome.cpp b/src/coreclr/debug/di/valuehome.cpp index d82379a0f4085f..da62a39f0f77a6 100644 --- a/src/coreclr/debug/di/valuehome.cpp +++ b/src/coreclr/debug/di/valuehome.cpp @@ -898,6 +898,7 @@ void RegisterValueHome::SetEnregisteredValue(MemoryRange src, bool fIsSigned) void RegisterValueHome::GetEnregisteredValue(MemoryRange dest) { + IDacDbiInterface::TargetInfo targetInfo; IfFailThrow(m_pFrame->GetProcess()->GetTargetInfo(&targetInfo)); if (targetInfo.arch != kArchX86) { From 8bb0a0c6e5184eef82172c644b26cee8f3a9324f Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Fri, 17 Jul 2026 11:55:57 -0700 Subject: [PATCH 14/26] Update rsthread.cpp --- src/coreclr/debug/di/rsthread.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index ddde51692b5b18..a392ea8de64e39 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -6759,7 +6759,6 @@ HRESULT CordbNativeFrame::GetLocalRegisterValue(CorDebugRegister reg, // The address of the given register is the address of the value // in this process. We have no remote address here. void *pLocalValue = (void*)GetAddressOfRegister(reg); - HRESULT hr = S_OK; EX_TRY { From 063685f084a7042b757c677f387a6f997216abc7 Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Fri, 17 Jul 2026 12:02:47 -0700 Subject: [PATCH 15/26] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/coreclr/inc/dacdbi.idl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/inc/dacdbi.idl b/src/coreclr/inc/dacdbi.idl index d23d76d7133f19..32926530d4ffa7 100644 --- a/src/coreclr/inc/dacdbi.idl +++ b/src/coreclr/inc/dacdbi.idl @@ -442,6 +442,6 @@ 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); + // Returns the target's processor architecture, OS family, and pointer size. + HRESULT GetTargetInfo([out] TargetInfo * pTargetInfo); }; From 8de27a5d35e7a59062bc90563b50ca7d3718bfe8 Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Fri, 17 Jul 2026 12:08:25 -0700 Subject: [PATCH 16/26] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/coreclr/debug/di/valuehome.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/debug/di/valuehome.cpp b/src/coreclr/debug/di/valuehome.cpp index da62a39f0f77a6..cf9f11fb0c0a31 100644 --- a/src/coreclr/debug/di/valuehome.cpp +++ b/src/coreclr/debug/di/valuehome.cpp @@ -900,7 +900,7 @@ void RegisterValueHome::GetEnregisteredValue(MemoryRange dest) { IDacDbiInterface::TargetInfo targetInfo; IfFailThrow(m_pFrame->GetProcess()->GetTargetInfo(&targetInfo)); - if (targetInfo.arch != kArchX86) + if (targetInfo.arch != IDacDbiInterface::kArchX86) { _ASSERTE(!"@TODO IA64/AMD64 -- Not Yet Implemented"); ThrowHR(E_NOTIMPL); From d82b109bb186063c5265371a5252a8b49eb4544e Mon Sep 17 00:00:00 2001 From: rcj1 Date: Fri, 17 Jul 2026 13:01:14 -0700 Subject: [PATCH 17/26] remove shim process finding impl --- src/coreclr/debug/di/shimdatatarget.h | 7 ---- src/coreclr/debug/di/shimprocess.cpp | 1 - src/coreclr/debug/di/shimremotedatatarget.cpp | 40 +------------------ src/coreclr/debug/di/valuehome.cpp | 2 +- 4 files changed, 2 insertions(+), 48 deletions(-) diff --git a/src/coreclr/debug/di/shimdatatarget.h b/src/coreclr/debug/di/shimdatatarget.h index 32f2eeadd9d398..bd77eab1da2ab2 100644 --- a/src/coreclr/debug/di/shimdatatarget.h +++ b/src/coreclr/debug/di/shimdatatarget.h @@ -15,8 +15,6 @@ // Function to invoke for typedef HRESULT (*FPContinueStatusChanged)(void * pUserData, DWORD dwThreadId, CORDB_CONTINUE_STATUS dwContinueStatus); -class ShimProcess; - //--------------------------------------------------------------------------------------- // Data target for a live process. This is used by Shim. // @@ -28,9 +26,6 @@ class ShimDataTarget : public ICorDebugMutableDataTarget, ICorDebugDataTarget4 // Allow hooking an implementation for ContinueStatusChanged. void HookContinueStatusChanged(FPContinueStatusChanged fpContinueStatusChanged, void * pUserData); - void SetShimProcess(ShimProcess * pShim) { m_pShim = pShim; } - ShimProcess * GetShimProcess() { return m_pShim; } - // Release any resources. Also called by destructor. virtual void Dispose() = 0; @@ -106,8 +101,6 @@ class ShimDataTarget : public ICorDebugMutableDataTarget, ICorDebugDataTarget4 FPContinueStatusChanged m_fpContinueStatusChanged; void * m_pContinueStatusChangedUserData; - ShimProcess * m_pShim = NULL; - // Reference count. LONG m_ref; }; diff --git a/src/coreclr/debug/di/shimprocess.cpp b/src/coreclr/debug/di/shimprocess.cpp index 3992cc5a5b5825..363cd07f926ff1 100644 --- a/src/coreclr/debug/di/shimprocess.cpp +++ b/src/coreclr/debug/di/shimprocess.cpp @@ -159,7 +159,6 @@ HRESULT ShimProcess::InitializeDataTarget(const ProcessDescriptor * pProcessDesc return hr; } m_pLiveDataTarget->HookContinueStatusChanged(ShimProcess::ContinueStatusChanged, this); - m_pLiveDataTarget->SetShimProcess(this); // Ref on pDataTarget is now 1. _ASSERTE(m_pLiveDataTarget != NULL); diff --git a/src/coreclr/debug/di/shimremotedatatarget.cpp b/src/coreclr/debug/di/shimremotedatatarget.cpp index 0d08df8624142b..4c79fb00bd980b 100644 --- a/src/coreclr/debug/di/shimremotedatatarget.cpp +++ b/src/coreclr/debug/di/shimremotedatatarget.cpp @@ -246,45 +246,7 @@ HRESULT STDMETHODCALLTYPE ShimRemoteDataTarget::GetPlatform( CorDebugPlatform *pPlatform) { - ShimProcess * pShim = GetShimProcess(); - if (pShim != NULL) - { - CordbProcess * pProcess = static_cast(pShim->GetProcess()); - if (pProcess != NULL) - { - IDacDbiInterface::TargetInfo targetInfo; - if (SUCCEEDED(pProcess->GetTargetInfo(&targetInfo))) - { - if (targetInfo.os == IDacDbiInterface::kOSWindows) - { - switch (targetInfo.arch) - { - case IDacDbiInterface::kArchX86: *pPlatform = CORDB_PLATFORM_WINDOWS_X86; return S_OK; - case IDacDbiInterface::kArchAMD64: *pPlatform = CORDB_PLATFORM_WINDOWS_AMD64; return S_OK; - case IDacDbiInterface::kArchArm: *pPlatform = CORDB_PLATFORM_WINDOWS_ARM; return S_OK; - case IDacDbiInterface::kArchArm64: *pPlatform = CORDB_PLATFORM_WINDOWS_ARM64; return S_OK; - default: break; - } - } - else if (targetInfo.os == IDacDbiInterface::kOSUnix) - { - switch (targetInfo.arch) - { - case IDacDbiInterface::kArchX86: *pPlatform = CORDB_PLATFORM_POSIX_X86; return S_OK; - case IDacDbiInterface::kArchAMD64: *pPlatform = CORDB_PLATFORM_POSIX_AMD64; return S_OK; - case IDacDbiInterface::kArchArm: *pPlatform = CORDB_PLATFORM_POSIX_ARM; return S_OK; - case IDacDbiInterface::kArchArm64: *pPlatform = CORDB_PLATFORM_POSIX_ARM64; return S_OK; - case IDacDbiInterface::kArchLoongArch64: *pPlatform = CORDB_PLATFORM_POSIX_LOONGARCH64; return S_OK; - case IDacDbiInterface::kArchRiscV64: *pPlatform = CORDB_PLATFORM_POSIX_RISCV64; return S_OK; - default: break; - } - } - return CORDBG_E_UNSUPPORTED; - } - } - } - - return E_FAIL; + return E_NOTIMPL; } // impl of interface method ICorDebugDataTarget::ReadVirtual diff --git a/src/coreclr/debug/di/valuehome.cpp b/src/coreclr/debug/di/valuehome.cpp index cf9f11fb0c0a31..09a4bac6dc9397 100644 --- a/src/coreclr/debug/di/valuehome.cpp +++ b/src/coreclr/debug/di/valuehome.cpp @@ -899,7 +899,7 @@ void RegisterValueHome::SetEnregisteredValue(MemoryRange src, bool fIsSigned) void RegisterValueHome::GetEnregisteredValue(MemoryRange dest) { IDacDbiInterface::TargetInfo targetInfo; - IfFailThrow(m_pFrame->GetProcess()->GetTargetInfo(&targetInfo)); + IfFailThrow(m_pProcess->GetTargetInfo(&targetInfo)); if (targetInfo.arch != IDacDbiInterface::kArchX86) { _ASSERTE(!"@TODO IA64/AMD64 -- Not Yet Implemented"); From 2b1ad306b13c8c99396f702496d0d89594ae6959 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Fri, 17 Jul 2026 14:16:27 -0700 Subject: [PATCH 18/26] fix --- src/coreclr/debug/di/process.cpp | 6 +++--- src/coreclr/debug/di/rsthread.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 6fa76f234f681f..0b91e6fbdc526c 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -6610,7 +6610,7 @@ HRESULT CordbProcess::FindPatchByAddress(CORDB_ADDRESS address, bool *pfPatchFou if (*pfPatchFound == false) { // Read one instruction from the faulting address... -#if defined(HOST_ARM) || defined(HOST_ARM64) +#if defined(TARGET_ARM) || defined(TARGET_ARM64) PRD_TYPE TrapCheck = 0; #else BYTE TrapCheck = 0; @@ -8360,9 +8360,9 @@ bool CordbProcess::IsBreakOpcodeAtAddress(const void * address) { // There should have been an int3 there already. Since we already put it in there, // we should be able to safely read it out. -#if defined(HOST_ARM) || defined(HOST_ARM64) +#if defined(TARGET_ARM) || defined(TARGET_ARM64) PRD_TYPE opcodeTest = 0; -#elif defined(HOST_AMD64) || defined(HOST_X86) +#elif defined(TARGET_AMD64) || defined(TARGET_X86) BYTE opcodeTest = 0; #else PORTABILITY_ASSERT("NYI: Architecture specific opcode type to read"); diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index a392ea8de64e39..51e51686d41de8 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -4361,9 +4361,9 @@ BOOL CordbUnmanagedThread::IsExceptionFromLastRaiseException(const EXCEPTION_REC // This flavor is assuming our caller already knows the opcode. HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress) { -#if defined(HOST_X86) || defined(HOST_AMD64) +#if defined(TARGET_X86) || defined(TARGET_AMD64) const BYTE patch = CORDbg_BREAK_INSTRUCTION; -#elif defined(HOST_ARM64) +#elif defined(TARGET_ARM64) const PRD_TYPE patch = CORDbg_BREAK_INSTRUCTION; #else const BYTE patch = 0; @@ -4378,10 +4378,10 @@ HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress) // Get the opcode that we're replacing. HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE * pOpcode) { -#if defined(HOST_X86) || defined(HOST_AMD64) +#if defined(TARGET_X86) || defined(TARGET_AMD64) // Read out opcode. 1 byte on x86 BYTE opcode; -#elif defined(HOST_ARM64) +#elif defined(TARGET_ARM64) // Read out opcode. 4 bytes on arm64 PRD_TYPE opcode; #else @@ -4405,10 +4405,10 @@ HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, P //----------------------------------------------------------------------------- HRESULT RemoveRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE opcode) { -#if defined(HOST_X86) || defined(HOST_AMD64) +#if defined(TARGET_X86) || defined(TARGET_AMD64) // Replace the BP w/ the opcode. BYTE opcode2 = (BYTE) opcode; -#elif defined(HOST_ARM64) +#elif defined(TARGET_ARM64) // 4 bytes on arm64 PRD_TYPE opcode2 = opcode; #else From 31b04ec15839c0d3c78bb97003f1b3e5f8132dc9 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Fri, 17 Jul 2026 16:24:20 -0700 Subject: [PATCH 19/26] remove dead code --- src/coreclr/debug/di/rspriv.h | 1 - src/coreclr/debug/di/rsthread.cpp | 84 ------------------------------- 2 files changed, 85 deletions(-) diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index c2221f45fd19e9..f60f0d3055aefd 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -10486,7 +10486,6 @@ class CordbUnmanagedThread : public CordbBase void HijackToRaiseException(); void RestoreFromRaiseExceptionHijack(); - void SaveRaiseExceptionEntryContext(); void ClearRaiseExceptionEntryContext(); BOOL IsExceptionFromLastRaiseException(const EXCEPTION_RECORD* pExceptionRecord); diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index 51e51686d41de8..b0246da570feb6 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -4206,90 +4206,6 @@ void CordbUnmanagedThread::RestoreFromRaiseExceptionHijack() _ASSERTE(SUCCEEDED(hr)); } -//----------------------------------------------------------------------------- -// Attempts to store the state of a thread currently entering RaiseException -// This grabs both a full context and enough state to determine what exception -// RaiseException should be raising. If any of the state can not be retrieved -// then this entrance to RaiseException is silently ignored -//----------------------------------------------------------------------------- -void CordbUnmanagedThread::SaveRaiseExceptionEntryContext() -{ - _ASSERTE(FALSE); // should be unused now - LOG((LF_CORDB, LL_INFO1000, "CP::SREEC: saving raise exception context.\n")); - _ASSERTE(!HasRaiseExceptionEntryCtx()); - _ASSERTE(!IsRaiseExceptionHijacked()); - HRESULT hr = S_OK; - DT_CONTEXT context; - context.ContextFlags = DT_CONTEXT_FULL; - DbiGetThreadContext(m_handle, &context); - // if the flag is set, unset it - // we don't want to be single stepping through RaiseException the second time - // sending out OOB SS events. Ultimately we will rethrow the exception which would - // cleared the SS flag anyways. - UnsetSSFlag(&context); - memcpy(&m_raiseExceptionEntryContext, &context, sizeof(DT_CONTEXT)); - - // calculate the exception that we would expect to come from this invocation of RaiseException - REMOTE_PTR pExceptionInformation = NULL; -#if defined(HOST_AMD64) - m_raiseExceptionExceptionCode = (DWORD)m_raiseExceptionEntryContext.Rcx; - m_raiseExceptionExceptionFlags = (DWORD)m_raiseExceptionEntryContext.Rdx; - m_raiseExceptionNumberParameters = (DWORD)m_raiseExceptionEntryContext.R8; - pExceptionInformation = (REMOTE_PTR)m_raiseExceptionEntryContext.R9; -#elif defined(HOST_ARM64) - m_raiseExceptionExceptionCode = (DWORD)m_raiseExceptionEntryContext.X0; - m_raiseExceptionExceptionFlags = (DWORD)m_raiseExceptionEntryContext.X1; - m_raiseExceptionNumberParameters = (DWORD)m_raiseExceptionEntryContext.X2; - pExceptionInformation = (REMOTE_PTR)m_raiseExceptionEntryContext.X3; -#elif defined(HOST_X86) - hr = m_pProcess->SafeReadStruct(PTR_TO_CORDB_ADDRESS((BYTE*)m_raiseExceptionEntryContext.Esp+4), &m_raiseExceptionExceptionCode); - if(FAILED(hr)) - { - LOG((LF_CORDB, LL_INFO1000, "CP::SREEC: failed to read exception code.\n")); - return; - } - hr = m_pProcess->SafeReadStruct(PTR_TO_CORDB_ADDRESS((BYTE*)m_raiseExceptionEntryContext.Esp+8), &m_raiseExceptionExceptionFlags); - if(FAILED(hr)) - { - LOG((LF_CORDB, LL_INFO1000, "CP::SREEC: failed to read exception flags.\n")); - return; - } - hr = m_pProcess->SafeReadStruct(PTR_TO_CORDB_ADDRESS((BYTE*)m_raiseExceptionEntryContext.Esp+12), &m_raiseExceptionNumberParameters); - if(FAILED(hr)) - { - LOG((LF_CORDB, LL_INFO1000, "CP::SREEC: failed to read number of parameters.\n")); - return; - } - hr = m_pProcess->SafeReadStruct(PTR_TO_CORDB_ADDRESS((BYTE*)m_raiseExceptionEntryContext.Esp+16), &pExceptionInformation); - if(FAILED(hr)) - { - LOG((LF_CORDB, LL_INFO1000, "CP::SREEC: failed to read exception information pointer.\n")); - return; - } -#else - _ASSERTE(!"Implement this for your platform"); - return; -#endif - LOG((LF_CORDB, LL_INFO1000, "CP::SREEC: RaiseException parameters are 0x%x 0x%x 0x%x 0x%p.\n", - m_raiseExceptionExceptionCode, m_raiseExceptionExceptionFlags, - m_raiseExceptionNumberParameters, pExceptionInformation)); - TargetBuffer exceptionInfoTargetBuffer(pExceptionInformation, sizeof(REMOTE_PTR)*m_raiseExceptionNumberParameters); - EX_TRY - { - m_pProcess->SafeReadBuffer(exceptionInfoTargetBuffer, (BYTE*)m_raiseExceptionExceptionInformation); - } - EX_CATCH_HRESULT(hr); - if(FAILED(hr)) - { - LOG((LF_CORDB, LL_INFO1000, "CP::SREEC: failed to read exception information.\n")); - return; - } - - // If everything was successful then set this flag, otherwise none of the above data is considered valid - SetState(CUTS_HasRaiseExceptionEntryCtx); - return; -} - //----------------------------------------------------------------------------- // Clears all the state saved in SaveRaiseExceptionContext and returns the thread // to the state as if RaiseException has yet to be called. This is typically called From 05147ef8784bb01ebfffcd948df6561daa8d06c8 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Fri, 17 Jul 2026 19:01:12 -0700 Subject: [PATCH 20/26] fix build --- src/coreclr/debug/di/process.cpp | 2 ++ src/coreclr/debug/di/rspriv.h | 2 ++ src/coreclr/debug/di/rsthread.cpp | 12 ++++++++++++ 3 files changed, 16 insertions(+) diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 0b91e6fbdc526c..3486d664cadf24 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -12478,7 +12478,9 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven DT_CONTEXT tempDebugContext; tempDebugContext.ContextFlags = DT_CONTEXT_FULL; DbiGetThreadContext(pUnmanagedThread->m_handle, &tempDebugContext); +#ifdef FEATURE_INTEROP_DEBUGGING CordbUnmanagedThread::LogContext(&tempDebugContext); +#endif // FEATURE_INTEROP_DEBUGGING #if defined(HOST_X86) || defined(HOST_AMD64) const ULONG_PTR breakpointOpcodeSize = 1; #elif defined(HOST_ARM64) diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index f60f0d3055aefd..4cbea933ee2ec5 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -10505,8 +10505,10 @@ class CordbUnmanagedThread : public CordbBase HRESULT RestoreLeafSeh(); #endif +#ifdef FEATURE_INTEROP_DEBUGGING // Logs basic data about a context to the debugging log static VOID LogContext(DT_CONTEXT* pContext); +#endif // FEATURE_INTEROP_DEBUGGING public: HANDLE m_handle; diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index b0246da570feb6..3b446a0a6fed96 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -3451,7 +3451,9 @@ HRESULT CordbUnmanagedThread::GetThreadContext(DT_CONTEXT* pContext) "HijackedForSync=%d RaiseExceptionHijacked=%d.\n", IsContextSet(), IsGenericHijacked(), IsBlockingForSync(), IsRaiseExceptionHijacked())); LOG((LF_CORDB, LL_INFO10000, "CUT::GTC: hijackCtx is:\n")); +#ifdef FEATURE_INTEROP_DEBUGGING LogContext(GetHijackCtx()); +#endif // FEATURE_INTEROP_DEBUGGING CORDbgCopyThreadContext(pContext, GetHijackCtx()); } // use the LS for M2UHandoff @@ -3483,7 +3485,9 @@ HRESULT CordbUnmanagedThread::GetThreadContext(DT_CONTEXT* pContext) { UnsetSSFlag(pContext); } +#ifdef FEATURE_INTEROP_DEBUGGING LogContext(pContext); +#endif // FEATURE_INTEROP_DEBUGGING return hr; } @@ -3498,7 +3502,9 @@ HRESULT CordbUnmanagedThread::SetThreadContext(DT_CONTEXT* pContext) LOG((LF_CORDB, LL_INFO10000, "CUT::STC: thread=0x%p, flags=0x%x.\n", this, pContext->ContextFlags)); +#ifdef FEATURE_INTEROP_DEBUGGING LogContext(pContext); +#endif // FEATURE_INTEROP_DEBUGGING // If the thread is first chance hijacked, then write the context into the remote process. If the thread is generic // hijacked, then update the copy of the context that we already have. Otherwise call the normal Win32 function. @@ -3596,6 +3602,7 @@ VOID CordbUnmanagedThread::EndStepping() } +#ifdef FEATURE_INTEROP_DEBUGGING // Writes some details of the given context into the debugger log VOID CordbUnmanagedThread::LogContext(DT_CONTEXT* pContext) { @@ -3620,6 +3627,7 @@ VOID CordbUnmanagedThread::LogContext(DT_CONTEXT* pContext) PORTABILITY_ASSERT("LogContext needs a PC and stack pointer."); #endif } +#endif // FEATURE_INTEROP_DEBUGGING // Hijacks this thread using the FirstChanceSuspend hijack HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync() @@ -3651,7 +3659,9 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync() // snapshot the current context so we can start spoofing it LOG((LF_CORDB, LL_INFO10000, "CUT::SFCHFS: hijackCtx started as:\n")); +#ifdef FEATURE_INTEROP_DEBUGGING LogContext(GetHijackCtx()); +#endif // FEATURE_INTEROP_DEBUGGING // Save the thread's full context + DT_CONTEXT_EXTENDED_REGISTERS // to avoid getting incomplete information and corrupt the thread context @@ -3676,7 +3686,9 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync() #endif CORDbgCopyThreadContext(GetHijackCtx(), &context); LOG((LF_CORDB, LL_INFO10000, "CUT::SFCHFS: thread=0x%x Hijacking for sync. Original context is:\n", this)); +#ifdef FEATURE_INTEROP_DEBUGGING LogContext(GetHijackCtx()); +#endif // FEATURE_INTEROP_DEBUGGING // We're hijacking now... SetState(CUTS_FirstChanceHijacked); From 266d1c2a6590505a181b6a3cff824cfe95595f94 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Tue, 21 Jul 2026 18:56:51 -0700 Subject: [PATCH 21/26] code review --- src/coreclr/debug/daccess/daccess.cpp | 49 +++++ src/coreclr/debug/di/process.cpp | 192 +++++++++++------- src/coreclr/debug/di/rspriv.h | 23 ++- src/coreclr/debug/di/rsthread.cpp | 68 ++----- src/coreclr/debug/di/shimdatatarget.h | 1 + src/coreclr/debug/di/shimpriv.h | 1 + src/coreclr/debug/di/shimremotedatatarget.cpp | 34 +++- 7 files changed, 242 insertions(+), 126 deletions(-) diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index 62f65d572e3052..df4f4defa29c6d 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -5099,6 +5099,55 @@ ClrDataAccess::Initialize(void) HRESULT hr; CLRDATA_ADDRESS base = { 0 }; + // + // We do not currently support cross-platform + // debugging. Verify that cross-platform is not + // being attempted. + // + + // Determine our platform based on the pre-processor macros set when we were built + +#ifdef TARGET_UNIX + #if defined(TARGET_X86) + CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_X86; + #elif defined(TARGET_AMD64) + CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_AMD64; + #elif defined(TARGET_ARM) + CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_ARM; + #elif defined(TARGET_ARM64) + CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_ARM64; + #elif defined(TARGET_LOONGARCH64) + CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_LOONGARCH64; + #elif defined(TARGET_RISCV64) + CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_RISCV64; + #else + #error Unknown Processor. + #endif +#else + #if defined(TARGET_X86) + CorDebugPlatform hostPlatform = CORDB_PLATFORM_WINDOWS_X86; + #elif defined(TARGET_AMD64) + CorDebugPlatform hostPlatform = CORDB_PLATFORM_WINDOWS_AMD64; + #elif defined(TARGET_ARM) + CorDebugPlatform hostPlatform = CORDB_PLATFORM_WINDOWS_ARM; + #elif defined(TARGET_ARM64) + CorDebugPlatform hostPlatform = CORDB_PLATFORM_WINDOWS_ARM64; + #else + #error Unknown Processor. + #endif +#endif + + CorDebugPlatform targetPlatform; + IfFailRet(m_pTarget->GetPlatform(&targetPlatform)); + + if (targetPlatform != hostPlatform) + { + // DAC fatal error: Platform mismatch - the platform reported by the data target + // is not what this version of mscordacwks.dll was built for. + return CORDBG_E_INCOMPATIBLE_PLATFORMS; + } + + // // Get the current DLL base for mscorwks globals. // In case of multiple-CLRs, there may be multiple dlls named "mscorwks". // code:OpenVirtualProcess can take the base address (clrInstanceId) to select exactly diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 3486d664cadf24..aca2d3d5823e38 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -6610,15 +6610,9 @@ HRESULT CordbProcess::FindPatchByAddress(CORDB_ADDRESS address, bool *pfPatchFou if (*pfPatchFound == false) { // Read one instruction from the faulting address... -#if defined(TARGET_ARM) || defined(TARGET_ARM64) - PRD_TYPE TrapCheck = 0; -#else - BYTE TrapCheck = 0; -#endif - - HRESULT hr2 = SafeReadStruct(address, &TrapCheck); - - if (SUCCEEDED(hr2) && (TrapCheck != CORDbg_BREAK_INSTRUCTION)) + ULONG32 TrapCheck = 0; + HRESULT hr2 = SafeReadOpcode(address, &TrapCheck); + if (SUCCEEDED(hr2) && (TrapCheck != (ULONG32) CORDbg_BREAK_INSTRUCTION)) { LOG((LF_CORDB, LL_INFO1000, "CP::FPBA: patchFound=true based on odd missing int 3 case.\n")); @@ -6655,16 +6649,19 @@ HRESULT CordbProcess::WriteMemory(CORDB_ADDRESS address, DWORD size, DWORD fCheckInt3 = configCheckInt3.val(CLRConfig::INTERNAL_DbgCheckInt3); if (fCheckInt3) { -#if defined(HOST_X86) || defined(HOST_AMD64) - if (size == 1 && buffer[0] == 0xCC) + IDacDbiInterface::TargetInfo targetInfo; + IfFailRet(GetTargetInfo(&targetInfo)); + if (targetInfo.arch == IDacDbiInterface::kArchX86 || targetInfo.arch == IDacDbiInterface::kArchAMD64) { - CONSISTENCY_CHECK_MSGF(false, - ("You're using ICorDebugProcess::WriteMemory() to write an 'int3' (1 byte 0xCC) at address 0x%p.\n" - "If you're trying to set a breakpoint, you should be using ICorDebugProcess::SetUnmanagedBreakpoint() instead.\n" - "(This assert is only enabled under the CLR knob DbgCheckInt3.)\n", - CORDB_ADDRESS_TO_PTR(address))); + if (size == 1 && buffer[0] == 0xCC) + { + CONSISTENCY_CHECK_MSGF(false, + ("You're using ICorDebugProcess::WriteMemory() to write an 'int3' (1 byte 0xCC) at address 0x%p.\n" + "If you're trying to set a breakpoint, you should be using ICorDebugProcess::SetUnmanagedBreakpoint() instead.\n" + "(This assert is only enabled under the CLR knob DbgCheckInt3.)\n", + CORDB_ADDRESS_TO_PTR(address))); + } } -#endif // HOST_X86 || HOST_AMD64 // check if we're replaced an opcode. if (size == 1) @@ -8156,6 +8153,88 @@ HRESULT CordbProcess::SafeReadBuffer(TargetBuffer tb, BYTE * pLocalBuffer, BOOL return S_OK; } +//----------------------------------------------------------------------------- +// Returns the width, in bytes, of the breakpoint opcode in the target's +// instruction stream, determined from the target's architecture at runtime. +//----------------------------------------------------------------------------- +HRESULT CordbProcess::GetTargetOpcodeSize(ULONG32 * pcbSize) +{ + _ASSERTE(pcbSize != NULL); + + IDacDbiInterface::TargetInfo targetInfo; + HRESULT hr = GetTargetInfo(&targetInfo); + if (FAILED(hr)) + return hr; + + switch (targetInfo.arch) + { + case IDacDbiInterface::kArchX86: + case IDacDbiInterface::kArchAMD64: + *pcbSize = 1; + break; + + case IDacDbiInterface::kArchArm: + *pcbSize = 2; + break; + + case IDacDbiInterface::kArchArm64: + case IDacDbiInterface::kArchLoongArch64: + case IDacDbiInterface::kArchRiscV64: + *pcbSize = 4; + break; + + default: + _ASSERTE(!"NYI: breakpoint opcode size for this target architecture"); + return E_NOTIMPL; + } + + return S_OK; +} + +//----------------------------------------------------------------------------- +// Reads the breakpoint opcode from the target using the target's instruction +// width. The value is zero-extended into pOpcode. +//----------------------------------------------------------------------------- +HRESULT CordbProcess::SafeReadOpcode(CORDB_ADDRESS pRemotePtr, ULONG32 * pOpcode) +{ + ULONG32 cbSize = 0; + HRESULT hr = GetTargetOpcodeSize(&cbSize); + if (FAILED(hr)) + return hr; + + _ASSERTE(cbSize <= sizeof(ULONG32)); + + *pOpcode = 0; + EX_TRY + { + TargetBuffer tb(pRemotePtr, cbSize); + SafeReadBuffer(tb, (PBYTE) pOpcode); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +//----------------------------------------------------------------------------- +// Writes an opcode to the target using the target's instruction width. +//----------------------------------------------------------------------------- +HRESULT CordbProcess::SafeWriteOpcode(CORDB_ADDRESS pRemotePtr, ULONG32 opcode) +{ + ULONG32 cbSize = 0; + HRESULT hr = GetTargetOpcodeSize(&cbSize); + if (FAILED(hr)) + return hr; + + _ASSERTE(cbSize <= sizeof(ULONG32)); + + EX_TRY + { + TargetBuffer tb(pRemotePtr, cbSize); + SafeWriteBuffer(tb, (const BYTE *) &opcode); + } + EX_CATCH_HRESULT(hr); + return hr; +} + CordbAppDomain * CordbProcess::GetAppDomain() { // Return the one and only app domain @@ -8360,18 +8439,12 @@ bool CordbProcess::IsBreakOpcodeAtAddress(const void * address) { // There should have been an int3 there already. Since we already put it in there, // we should be able to safely read it out. -#if defined(TARGET_ARM) || defined(TARGET_ARM64) - PRD_TYPE opcodeTest = 0; -#elif defined(TARGET_AMD64) || defined(TARGET_X86) - BYTE opcodeTest = 0; -#else - PORTABILITY_ASSERT("NYI: Architecture specific opcode type to read"); -#endif + ULONG32 opcodeTest = 0; - HRESULT hr = SafeReadStruct(PTR_TO_CORDB_ADDRESS(address), &opcodeTest); + HRESULT hr = SafeReadOpcode(PTR_TO_CORDB_ADDRESS(address), &opcodeTest); SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr); - return (opcodeTest == CORDbg_BREAK_INSTRUCTION); + return (opcodeTest == (ULONG32) CORDbg_BREAK_INSTRUCTION); } #endif // FEATURE_INTEROP_DEBUGGING @@ -8425,20 +8498,14 @@ CordbProcess::SetUnmanagedBreakpointInternal(CORDB_ADDRESS address, ULONG32 bufs HRESULT hr = S_OK; NativePatch * p = NULL; -#if defined(TARGET_X86) || defined(TARGET_AMD64) - const BYTE patch = CORDbg_BREAK_INSTRUCTION; - BYTE opcode; -#elif defined(TARGET_ARM64) - const PRD_TYPE patch = CORDbg_BREAK_INSTRUCTION; - PRD_TYPE opcode; -#else - PORTABILITY_ASSERT("NYI: CordbProcess::SetUnmanagedBreakpoint, interop debugging NYI on this platform"); - hr = E_NOTIMPL; - goto ErrExit; -#endif + ULONG32 opcode = 0; + ULONG32 cbOpcode = 0; + hr = GetTargetOpcodeSize(&cbOpcode); + if (FAILED(hr)) + goto ErrExit; // Make sure args are good - if ((buffer == NULL) || (bufsize < sizeof(patch)) || (bufLen == NULL)) + if ((buffer == NULL) || (bufsize < cbOpcode) || (bufLen == NULL)) { hr = E_INVALIDARG; goto ErrExit; @@ -8459,24 +8526,14 @@ CordbProcess::SetUnmanagedBreakpointInternal(CORDB_ADDRESS address, ULONG32 bufs goto ErrExit; } - - // Read out opcode. 1 byte on x86 - hr = ApplyRemotePatch(this, CORDB_ADDRESS_TO_PTR(address), &p->opcode); if (FAILED(hr)) goto ErrExit; // It's all successful, so now update our out-params & internal bookkeaping. -#if defined(TARGET_X86) || defined(TARGET_AMD64) - opcode = (BYTE)p->opcode; - buffer[0] = opcode; -#elif defined(TARGET_ARM64) opcode = p->opcode; - memcpy_s(buffer, bufsize, &opcode, sizeof(opcode)); -#else - PORTABILITY_ASSERT("NYI: CordbProcess::SetUnmanagedBreakpoint, interop debugging NYI on this platform"); -#endif - *bufLen = sizeof(opcode); + memcpy_s(buffer, bufsize, &opcode, cbOpcode); + *bufLen = cbOpcode; p->pAddress = CORDB_ADDRESS_TO_PTR(address); p->opcode = opcode; @@ -8515,7 +8572,7 @@ CordbProcess::ClearUnmanagedBreakpoint(CORDB_ADDRESS address) _ASSERTE(!ThreadHoldsProcessLock()); HRESULT hr = S_OK; - PRD_TYPE opcode; + ULONG32 opcode; Lock(); @@ -10390,7 +10447,7 @@ bool CordbProcess::HandleSetThreadContextNeeded(DWORD dwThreadId) bool m_fIsInPlaceSingleStep = false; bool m_fHasDebuggerPatchSkip = false; bool m_fClearSetIP = false; - PRD_TYPE m_opcode = 0; + ULONG32 m_opcode = 0; public: void Update(DT_CONTEXT * pContext) @@ -10400,7 +10457,7 @@ bool CordbProcess::HandleSetThreadContextNeeded(DWORD dwThreadId) this->m_fIsInPlaceSingleStep = (pContext->R8 & 0x1) != 0; this->m_fHasDebuggerPatchSkip = (pContext->R8 & 0x2) != 0; this->m_fClearSetIP = (pContext->R8 & 0x4) != 0; - this->m_opcode = (PRD_TYPE)pContext->R9; + this->m_opcode = (ULONG32)pContext->R9; } TADDR ContextAddr() { return m_lsContextAddr; } @@ -10408,7 +10465,7 @@ bool CordbProcess::HandleSetThreadContextNeeded(DWORD dwThreadId) bool IsInPlaceSingleStep() { return m_fIsInPlaceSingleStep; } bool HasDebuggerPatchSkip() { return m_fHasDebuggerPatchSkip; } bool IsClearSetIP() { return m_fClearSetIP; } - PRD_TYPE Opcode() { return m_opcode; } + ULONG32 Opcode() { return m_opcode; } HRESULT IsValid() { @@ -10622,7 +10679,7 @@ bool CordbProcess::HandleSetThreadContextNeeded(DWORD dwThreadId) #endif } -HRESULT CordbProcess::EnableInPlaceSingleStepping(UnmanagedThreadTracker * pCurThread, CORDB_ADDRESS_TYPE *patchSkipAddr, PRD_TYPE opcode) +HRESULT CordbProcess::EnableInPlaceSingleStepping(UnmanagedThreadTracker * pCurThread, CORDB_ADDRESS_TYPE *patchSkipAddr, ULONG32 opcode) { if (pCurThread == NULL || patchSkipAddr == NULL) { @@ -12481,14 +12538,9 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven #ifdef FEATURE_INTEROP_DEBUGGING CordbUnmanagedThread::LogContext(&tempDebugContext); #endif // FEATURE_INTEROP_DEBUGGING -#if defined(HOST_X86) || defined(HOST_AMD64) - const ULONG_PTR breakpointOpcodeSize = 1; -#elif defined(HOST_ARM64) - const ULONG_PTR breakpointOpcodeSize = 4; -#else - const ULONG_PTR breakpointOpcodeSize = 1; - PORTABILITY_ASSERT("NYI: Breakpoint size offset for this platform"); -#endif + + ULONG32 breakpointOpcodeSize = 0; + IfFailThrow(GetTargetOpcodeSize(&breakpointOpcodeSize)); _ASSERTE(CORDbgGetIP(&tempDebugContext) == pEvent->u.Exception.ExceptionRecord.ExceptionAddress || (DWORD)(size_t)CORDbgGetIP(&tempDebugContext) == ((DWORD)(size_t)pEvent->u.Exception.ExceptionRecord.ExceptionAddress)+breakpointOpcodeSize); } @@ -12704,10 +12756,13 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven // Because hijacks don't return normally they might have pushed handlers without poping them // back off. To take care of that we explicitly restore the old SEH chain. - #ifdef HOST_X86 - hr = pUnmanagedThread->RestoreLeafSeh(); - _ASSERTE(SUCCEEDED(hr)); - #endif + IDacDbiInterface::TargetInfo targetInfo; + IfFailThrow(GetTargetInfo(&targetInfo)); + if (targetInfo.arch == IDacDbiInterface::kArchX86) + { + hr = pUnmanagedThread->RestoreLeafSeh(); + _ASSERTE(SUCCEEDED(hr)); + } } else { @@ -13076,6 +13131,7 @@ bool CordbProcess::IsUnmanagedThreadHijacked(ICorDebugThread * pICorDebugThread) // this here. We have a check such that if we do get headers, the value won't change underneath us. #define MY_DBG_FORCE_CONTINUE ((DWORD )0x00010003L) #ifndef DBG_FORCE_CONTINUE + #define DBG_FORCE_CONTINUE MY_DBG_FORCE_CONTINUE #else static_assert(DBG_FORCE_CONTINUE == MY_DBG_FORCE_CONTINUE); @@ -13111,7 +13167,7 @@ void EnableDebugTrace(CordbUnmanagedThread *ut) return; // Give us a nop so that we can setip in the optimized case. -#ifdef HOST_X86 +#if defined(HOST_X86) __asm { nop } diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index 4cbea933ee2ec5..15ba99e94b0eec 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -1153,11 +1153,11 @@ typedef enum { struct NativePatch { void * pAddress; // pointer into the LS address space. - PRD_TYPE opcode; // opcode to restore with. + ULONG32 opcode; // opcode to restore with. inline bool operator==(NativePatch p2) { - return memcmp(this, &p2, sizeof(p2)) == 0; + return (pAddress == p2.pAddress) && (opcode == p2.opcode); } }; @@ -1166,13 +1166,13 @@ struct NativePatch //----------------------------------------------------------------------------- // Remove the int3 from the remote address -HRESULT RemoveRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE opcode); +HRESULT RemoveRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, ULONG32 opcode); // This flavor is assuming our caller already knows the opcode. HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress); // Apply the patch and get the opcode that we're replacing. -HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE * pOpcode); +HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, ULONG32 * pOpcode); class CordbHashTable; @@ -3279,6 +3279,12 @@ class CordbProcess : // Writes a buffer to the target void SafeWriteBuffer(TargetBuffer tb, const BYTE * pLocalBuffer); + // Reads the breakpoint opcode from the target, using the target's instruction width. + HRESULT SafeReadOpcode(CORDB_ADDRESS pRemotePtr, ULONG32 * pOpcode); + + // Writes an opcode to the target, using the target's instruction width. + HRESULT SafeWriteOpcode(CORDB_ADDRESS pRemotePtr, ULONG32 opcode); + #if defined(FEATURE_INTEROP_DEBUGGING) void DuplicateHandleToLocalProcess(HANDLE * pLocalHandle, RemoteHANDLE * pRemoteHandle); #endif // FEATURE_INTEROP_DEBUGGING @@ -3602,6 +3608,9 @@ class CordbProcess : HRESULT GetTargetInfo(IDacDbiInterface::TargetInfo * pTargetInfo); + // Get the width, in bytes, of the breakpoint opcode in the target's instruction stream. + HRESULT GetTargetOpcodeSize(ULONG32 * pcbSize); + // Get the data-target, which provides access to the debuggee. ICorDebugDataTarget * GetDataTarget(); @@ -4111,7 +4120,7 @@ class CordbProcess : CUnmanagedThreadHashTableImpl m_unmanagedThreadHashTable; DWORD m_dwOutOfProcessStepping; bool m_fOutOfProcessSetThreadContextEventReceived; - HRESULT EnableInPlaceSingleStepping(UnmanagedThreadTracker * pCurThread, CORDB_ADDRESS_TYPE *patchSkipAddr, PRD_TYPE opcode); + HRESULT EnableInPlaceSingleStepping(UnmanagedThreadTracker * pCurThread, CORDB_ADDRESS_TYPE *patchSkipAddr, ULONG32 opcode); public: void HandleDebugEventForInPlaceStepping(const DEBUG_EVENT * pEvent); bool CanDetach(); // Must only be called on the Win32ET, determines if it is safe to detach. Only used by W32ETA_CAN_DETACH @@ -10498,12 +10507,10 @@ class CordbUnmanagedThread : public CordbBase return (DWORD) this->m_id; } -#ifdef HOST_X86 // Stores the thread's current leaf SEH handler HRESULT SaveCurrentLeafSeh(); // Restores the thread's leaf SEH handler from the previously saved value HRESULT RestoreLeafSeh(); -#endif #ifdef FEATURE_INTEROP_DEBUGGING // Logs basic data about a context to the debugging log @@ -10548,10 +10555,8 @@ class CordbUnmanagedThread : public CordbBase ULONG_PTR m_raiseExceptionExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; -#ifdef HOST_X86 // the SEH handler which was the leaf when SaveCurrentSeh was called (prior to hijack) REMOTE_PTR m_pSavedLeafSeh; -#endif HRESULT EnableSSAfterBP(); diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index 3b446a0a6fed96..e7f43325042b49 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -2734,9 +2734,7 @@ CordbUnmanagedThread::CordbUnmanagedThread(CordbProcess *pProcess, DWORD dwThrea m_pTLSExtendedArray(NULL), m_state(CUTS_None), m_originalHandler(NULL), -#ifdef HOST_X86 m_pSavedLeafSeh(NULL), -#endif m_continueCountCached(0) { m_pLeftSideContext.Set(NULL); @@ -2873,7 +2871,6 @@ VOID CordbUnmanagedThread::VerifyFSChain() return; }*/ -#ifdef HOST_X86 HRESULT CordbUnmanagedThread::SaveCurrentLeafSeh() { _ASSERTE(m_pSavedLeafSeh == NULL); @@ -2900,7 +2897,6 @@ HRESULT CordbUnmanagedThread::RestoreLeafSeh() m_pSavedLeafSeh = NULL; return S_OK; } -#endif // Read the contents from the LS's Predefined TLS block. // This is an auxiliary TLS storage array-of-void*, indexed off the TLS. @@ -3770,11 +3766,14 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijack(EHijackReason::EHijackReaso { // We save off the SEH handler on X86 to make sure we restore it properly after the hijack is complete // The hijacks don't return normally and the SEH chain might have handlers added that don't get removed by default -#ifdef HOST_X86 - hr = SaveCurrentLeafSeh(); - if(FAILED(hr)) - ThrowHR(hr); -#endif + IDacDbiInterface::TargetInfo targetInfo; + IfFailThrow(GetProcess()->GetTargetInfo(&targetInfo)); + if (targetInfo.arch == IDacDbiInterface::kArchX86) + { + hr = SaveCurrentLeafSeh(); + if(FAILED(hr)) + ThrowHR(hr); + } CORDB_ADDRESS LSContextAddr; IfFailThrow(GetProcess()->GetDAC()->Hijack(VMPTR_Thread::NullPtr(), GetOSTid(), @@ -4043,9 +4042,12 @@ void CordbUnmanagedThread::SetupForSkipBreakpoint(NativePatch * pNativePatch) fTrapOnSkip = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgTrapOnSkip); } #endif -#if defined(HOST_X86) - STRESS_LOG2(LF_CORDB, LL_INFO100, "CUT::SetupSkip. addr=%p. Opcode=%x\n", pNativePatch->pAddress, (DWORD) pNativePatch->opcode); -#endif + IDacDbiInterface::TargetInfo targetInfo; + IfFailThrow(GetProcess()->GetTargetInfo(&targetInfo)); + if (targetInfo.arch == IDacDbiInterface::kArchX86) + { + STRESS_LOG2(LF_CORDB, LL_INFO100, "CUT::SetupSkip. addr=%p. Opcode=%x\n", pNativePatch->pAddress, (DWORD) pNativePatch->opcode); + } // Replace the BP w/ the opcode. RemoveRemotePatch(GetProcess(), pNativePatch->pAddress, pNativePatch->opcode); @@ -4289,41 +4291,22 @@ BOOL CordbUnmanagedThread::IsExceptionFromLastRaiseException(const EXCEPTION_REC // This flavor is assuming our caller already knows the opcode. HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress) { -#if defined(TARGET_X86) || defined(TARGET_AMD64) - const BYTE patch = CORDbg_BREAK_INSTRUCTION; -#elif defined(TARGET_ARM64) - const PRD_TYPE patch = CORDbg_BREAK_INSTRUCTION; -#else - const BYTE patch = 0; - PORTABILITY_ASSERT("NYI: ApplyRemotePatch for this platform"); -#endif - HRESULT hr = pProcess->SafeWriteStruct(PTR_TO_CORDB_ADDRESS(pRemoteAddress), &patch); + ULONG32 patch = CORDbg_BREAK_INSTRUCTION; + HRESULT hr = pProcess->SafeWriteOpcode(PTR_TO_CORDB_ADDRESS(pRemoteAddress), patch); SIMPLIFYING_ASSUMPTION_SUCCEEDED(hr); return S_OK; } // Get the opcode that we're replacing. -HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE * pOpcode) +HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, ULONG32 * pOpcode) { -#if defined(TARGET_X86) || defined(TARGET_AMD64) - // Read out opcode. 1 byte on x86 - BYTE opcode; -#elif defined(TARGET_ARM64) - // Read out opcode. 4 bytes on arm64 - PRD_TYPE opcode; -#else - BYTE opcode; - PORTABILITY_ASSERT("NYI: ApplyRemotePatch for this platform"); -#endif - - HRESULT hr = pProcess->SafeReadStruct(PTR_TO_CORDB_ADDRESS(pRemoteAddress), &opcode); + HRESULT hr = pProcess->SafeReadOpcode(PTR_TO_CORDB_ADDRESS(pRemoteAddress), pOpcode); if (FAILED(hr)) { return hr; } - *pOpcode = (PRD_TYPE) opcode; ApplyRemotePatch(pProcess, pRemoteAddress); return S_OK; } @@ -4331,20 +4314,9 @@ HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, P //----------------------------------------------------------------------------- // Remove the int3 from the remote address //----------------------------------------------------------------------------- -HRESULT RemoveRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE opcode) +HRESULT RemoveRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, ULONG32 opcode) { -#if defined(TARGET_X86) || defined(TARGET_AMD64) - // Replace the BP w/ the opcode. - BYTE opcode2 = (BYTE) opcode; -#elif defined(TARGET_ARM64) - // 4 bytes on arm64 - PRD_TYPE opcode2 = opcode; -#else - PRD_TYPE opcode2 = opcode; - PORTABILITY_ASSERT("NYI: RemoveRemotePatch for this platform"); -#endif - - pProcess->SafeWriteStruct(PTR_TO_CORDB_ADDRESS(pRemoteAddress), &opcode2); + pProcess->SafeWriteOpcode(PTR_TO_CORDB_ADDRESS(pRemoteAddress), opcode); // This may fail because the module has been unloaded. In which case, the patch is also // gone so it makes sense to return success. diff --git a/src/coreclr/debug/di/shimdatatarget.h b/src/coreclr/debug/di/shimdatatarget.h index bd77eab1da2ab2..c2e92c217dd6c1 100644 --- a/src/coreclr/debug/di/shimdatatarget.h +++ b/src/coreclr/debug/di/shimdatatarget.h @@ -15,6 +15,7 @@ // Function to invoke for typedef HRESULT (*FPContinueStatusChanged)(void * pUserData, DWORD dwThreadId, CORDB_CONTINUE_STATUS dwContinueStatus); + //--------------------------------------------------------------------------------------- // Data target for a live process. This is used by Shim. // diff --git a/src/coreclr/debug/di/shimpriv.h b/src/coreclr/debug/di/shimpriv.h index 4c575e480a9a8f..24c3b72a895318 100644 --- a/src/coreclr/debug/di/shimpriv.h +++ b/src/coreclr/debug/di/shimpriv.h @@ -1047,3 +1047,4 @@ class ShimFrameEnum : public ICorDebugFrameEnum #endif // SHIMPRIV_H + diff --git a/src/coreclr/debug/di/shimremotedatatarget.cpp b/src/coreclr/debug/di/shimremotedatatarget.cpp index 4c79fb00bd980b..b1074bc418c5e5 100644 --- a/src/coreclr/debug/di/shimremotedatatarget.cpp +++ b/src/coreclr/debug/di/shimremotedatatarget.cpp @@ -246,7 +246,39 @@ HRESULT STDMETHODCALLTYPE ShimRemoteDataTarget::GetPlatform( CorDebugPlatform *pPlatform) { - return E_NOTIMPL; +#ifdef TARGET_UNIX + #if defined(TARGET_X86) + *pPlatform = CORDB_PLATFORM_POSIX_X86; + #elif defined(TARGET_AMD64) + *pPlatform = CORDB_PLATFORM_POSIX_AMD64; + #elif defined(TARGET_ARM) + *pPlatform = CORDB_PLATFORM_POSIX_ARM; + #elif defined(TARGET_ARM64) + *pPlatform = CORDB_PLATFORM_POSIX_ARM64; + #elif defined(TARGET_LOONGARCH64) + *pPlatform = CORDB_PLATFORM_POSIX_LOONGARCH64; + #elif defined(TARGET_RISCV64) + *pPlatform = CORDB_PLATFORM_POSIX_RISCV64; + #else + #error Unknown Processor. + #endif +#else + #if defined(TARGET_X86) + *pPlatform = CORDB_PLATFORM_WINDOWS_X86; + #elif defined(TARGET_AMD64) + *pPlatform = CORDB_PLATFORM_WINDOWS_AMD64; + #elif defined(TARGET_ARM) + *pPlatform = CORDB_PLATFORM_WINDOWS_ARM; + #elif defined(TARGET_ARM64) + *pPlatform = CORDB_PLATFORM_WINDOWS_ARM64; + #elif defined(TARGET_LOONGARCH64) + *pPlatform = CORDB_PLATFORM_WINDOWS_LOONGARCH64; + #else + #error Unknown Processor. + #endif +#endif + + return S_OK; } // impl of interface method ICorDebugDataTarget::ReadVirtual From 2cbda2d65aff075c771eb6c2a59fe2d66a6f9692 Mon Sep 17 00:00:00 2001 From: Rachel Jarvi Date: Wed, 22 Jul 2026 16:42:08 -0700 Subject: [PATCH 22/26] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/coreclr/debug/di/process.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index aca2d3d5823e38..8bed796d3ebd2e 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -6650,8 +6650,8 @@ HRESULT CordbProcess::WriteMemory(CORDB_ADDRESS address, DWORD size, if (fCheckInt3) { IDacDbiInterface::TargetInfo targetInfo; - IfFailRet(GetTargetInfo(&targetInfo)); - if (targetInfo.arch == IDacDbiInterface::kArchX86 || targetInfo.arch == IDacDbiInterface::kArchAMD64) + if (SUCCEEDED(GetTargetInfo(&targetInfo)) && + (targetInfo.arch == IDacDbiInterface::kArchX86 || targetInfo.arch == IDacDbiInterface::kArchAMD64)) { if (size == 1 && buffer[0] == 0xCC) { From c3d8f5a908d4fc8c8c122323124ac0bbdae0cc67 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Wed, 22 Jul 2026 16:44:13 -0700 Subject: [PATCH 23/26] code review --- src/coreclr/debug/di/cordb.cpp | 11 ++--------- src/coreclr/debug/di/rspriv.h | 2 -- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/coreclr/debug/di/cordb.cpp b/src/coreclr/debug/di/cordb.cpp index 657ddcb4eecec8..af863d32a05686 100644 --- a/src/coreclr/debug/di/cordb.cpp +++ b/src/coreclr/debug/di/cordb.cpp @@ -18,13 +18,6 @@ #include "dbgtransportmanager.h" #endif // FEATURE_DBGIPC_TRANSPORT_DI -#if defined(HOST_UNIX) || defined(__ANDROID__) -// Local (in-process) debugging is not supported for UNIX and Android. -#define SUPPORT_LOCAL_DEBUGGING 0 -#else -#define SUPPORT_LOCAL_DEBUGGING 1 -#endif - //----------------------------------------------------------------------------- // SxS Versioning story for Mscordbi (ICorDebug + friends) //----------------------------------------------------------------------------- @@ -437,7 +430,7 @@ DbiGetThreadContext(HANDLE hThread, DT_CONTEXT *lpContext) { // if we aren't local debugging this isn't going to work -#if !defined(HOST_ARM) || defined(FEATURE_DBGIPC_TRANSPORT_DI) || !SUPPORT_LOCAL_DEBUGGING +#if !defined(HOST_ARM) || defined(FEATURE_DBGIPC_TRANSPORT_DI) || defined(__ANDROID__) _ASSERTE(!"Can't use local GetThreadContext remotely, this needed to go to datatarget"); return FALSE; #else @@ -476,7 +469,7 @@ BOOL DbiSetThreadContext(HANDLE hThread, const DT_CONTEXT *lpContext) { -#if !defined(HOST_ARM) || defined(FEATURE_DBGIPC_TRANSPORT_DI) || !SUPPORT_LOCAL_DEBUGGING +#if !defined(HOST_ARM) || defined(FEATURE_DBGIPC_TRANSPORT_DI) || !defined(__ANDROID__) _ASSERTE(!"Can't use local GetThreadContext remotely, this needed to go to datatarget"); return FALSE; #else diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index 15ba99e94b0eec..40f6db5e558b12 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -11395,13 +11395,11 @@ inline void ValidateOrThrow(const void * p) // aligns argBase on platforms that require it else it's a no-op inline void AlignAddressForType(CordbType* pArgType, CORDB_ADDRESS& argBase) { -#ifdef FEATURE_64BIT_ALIGNMENT BOOL align = FALSE; IfFailThrow(pArgType->RequiresAlign8(&align)); if (align) argBase = ALIGN_ADDRESS(argBase, 8); -#endif } //----------------------------------------------------------------------------- From 847468ecc518a7c1a074a4c69ace03f1302e5f91 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 23 Jul 2026 11:31:18 -0700 Subject: [PATCH 24/26] E --- src/coreclr/debug/di/cordb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/debug/di/cordb.cpp b/src/coreclr/debug/di/cordb.cpp index af863d32a05686..6010e1404ee4e2 100644 --- a/src/coreclr/debug/di/cordb.cpp +++ b/src/coreclr/debug/di/cordb.cpp @@ -469,7 +469,7 @@ BOOL DbiSetThreadContext(HANDLE hThread, const DT_CONTEXT *lpContext) { -#if !defined(HOST_ARM) || defined(FEATURE_DBGIPC_TRANSPORT_DI) || !defined(__ANDROID__) +#if !defined(HOST_ARM) || defined(FEATURE_DBGIPC_TRANSPORT_DI) || defined(__ANDROID__) _ASSERTE(!"Can't use local GetThreadContext remotely, this needed to go to datatarget"); return FALSE; #else From d2595a7a2a7a8ecaa11829190502e2fe772500da Mon Sep 17 00:00:00 2001 From: rcj1 Date: Thu, 23 Jul 2026 13:08:50 -0700 Subject: [PATCH 25/26] fix build --- src/coreclr/debug/di/process.cpp | 2 -- src/coreclr/debug/di/rspriv.h | 2 -- src/coreclr/debug/di/rsthread.cpp | 18 +++--------------- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 8bed796d3ebd2e..23c00bac733bd8 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -12535,9 +12535,7 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven DT_CONTEXT tempDebugContext; tempDebugContext.ContextFlags = DT_CONTEXT_FULL; DbiGetThreadContext(pUnmanagedThread->m_handle, &tempDebugContext); -#ifdef FEATURE_INTEROP_DEBUGGING CordbUnmanagedThread::LogContext(&tempDebugContext); -#endif // FEATURE_INTEROP_DEBUGGING ULONG32 breakpointOpcodeSize = 0; IfFailThrow(GetTargetOpcodeSize(&breakpointOpcodeSize)); diff --git a/src/coreclr/debug/di/rspriv.h b/src/coreclr/debug/di/rspriv.h index 40f6db5e558b12..95074c76ea3c84 100644 --- a/src/coreclr/debug/di/rspriv.h +++ b/src/coreclr/debug/di/rspriv.h @@ -10512,10 +10512,8 @@ class CordbUnmanagedThread : public CordbBase // Restores the thread's leaf SEH handler from the previously saved value HRESULT RestoreLeafSeh(); -#ifdef FEATURE_INTEROP_DEBUGGING // Logs basic data about a context to the debugging log static VOID LogContext(DT_CONTEXT* pContext); -#endif // FEATURE_INTEROP_DEBUGGING public: HANDLE m_handle; diff --git a/src/coreclr/debug/di/rsthread.cpp b/src/coreclr/debug/di/rsthread.cpp index e7f43325042b49..16eaf49d1215d4 100644 --- a/src/coreclr/debug/di/rsthread.cpp +++ b/src/coreclr/debug/di/rsthread.cpp @@ -3447,9 +3447,7 @@ HRESULT CordbUnmanagedThread::GetThreadContext(DT_CONTEXT* pContext) "HijackedForSync=%d RaiseExceptionHijacked=%d.\n", IsContextSet(), IsGenericHijacked(), IsBlockingForSync(), IsRaiseExceptionHijacked())); LOG((LF_CORDB, LL_INFO10000, "CUT::GTC: hijackCtx is:\n")); -#ifdef FEATURE_INTEROP_DEBUGGING LogContext(GetHijackCtx()); -#endif // FEATURE_INTEROP_DEBUGGING CORDbgCopyThreadContext(pContext, GetHijackCtx()); } // use the LS for M2UHandoff @@ -3481,9 +3479,7 @@ HRESULT CordbUnmanagedThread::GetThreadContext(DT_CONTEXT* pContext) { UnsetSSFlag(pContext); } -#ifdef FEATURE_INTEROP_DEBUGGING LogContext(pContext); -#endif // FEATURE_INTEROP_DEBUGGING return hr; } @@ -3498,9 +3494,7 @@ HRESULT CordbUnmanagedThread::SetThreadContext(DT_CONTEXT* pContext) LOG((LF_CORDB, LL_INFO10000, "CUT::STC: thread=0x%p, flags=0x%x.\n", this, pContext->ContextFlags)); -#ifdef FEATURE_INTEROP_DEBUGGING LogContext(pContext); -#endif // FEATURE_INTEROP_DEBUGGING // If the thread is first chance hijacked, then write the context into the remote process. If the thread is generic // hijacked, then update the copy of the context that we already have. Otherwise call the normal Win32 function. @@ -3598,21 +3592,20 @@ VOID CordbUnmanagedThread::EndStepping() } -#ifdef FEATURE_INTEROP_DEBUGGING // Writes some details of the given context into the debugger log VOID CordbUnmanagedThread::LogContext(DT_CONTEXT* pContext) { -#if defined(HOST_X86) +#if defined(TARGET_X86) LOG((LF_CORDB, LL_INFO10000, "CUT::LC: Eip=0x%08x, Esp=0x%08x, Eflags=0x%08x\n", pContext->Eip, pContext->Esp, pContext->EFlags)); -#elif defined(HOST_AMD64) +#elif defined(TARGET_AMD64) LOG((LF_CORDB, LL_INFO10000, "CUT::LC: Rip=" FMT_ADDR ", Rsp=" FMT_ADDR ", Eflags=0x%08x\n", DBG_ADDR(pContext->Rip), DBG_ADDR(pContext->Rsp), pContext->EFlags)); // EFlags is still 32bits on AMD64 -#elif defined(HOST_ARM64) +#elif defined(TARGET_ARM64) LOG((LF_CORDB, LL_INFO10000, "CUT::LC: Pc=" FMT_ADDR ", Sp=" FMT_ADDR ", Lr=" FMT_ADDR ", Cpsr=" FMT_ADDR "\n", DBG_ADDR(pContext->Pc), @@ -3623,7 +3616,6 @@ VOID CordbUnmanagedThread::LogContext(DT_CONTEXT* pContext) PORTABILITY_ASSERT("LogContext needs a PC and stack pointer."); #endif } -#endif // FEATURE_INTEROP_DEBUGGING // Hijacks this thread using the FirstChanceSuspend hijack HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync() @@ -3655,9 +3647,7 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync() // snapshot the current context so we can start spoofing it LOG((LF_CORDB, LL_INFO10000, "CUT::SFCHFS: hijackCtx started as:\n")); -#ifdef FEATURE_INTEROP_DEBUGGING LogContext(GetHijackCtx()); -#endif // FEATURE_INTEROP_DEBUGGING // Save the thread's full context + DT_CONTEXT_EXTENDED_REGISTERS // to avoid getting incomplete information and corrupt the thread context @@ -3682,9 +3672,7 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync() #endif CORDbgCopyThreadContext(GetHijackCtx(), &context); LOG((LF_CORDB, LL_INFO10000, "CUT::SFCHFS: thread=0x%x Hijacking for sync. Original context is:\n", this)); -#ifdef FEATURE_INTEROP_DEBUGGING LogContext(GetHijackCtx()); -#endif // FEATURE_INTEROP_DEBUGGING // We're hijacking now... SetState(CUTS_FirstChanceHijacked); From 22e98b9619afbc98ee84e97d809b23e417081a44 Mon Sep 17 00:00:00 2001 From: rcj1 Date: Fri, 24 Jul 2026 19:34:49 -0700 Subject: [PATCH 26/26] CCR --- src/coreclr/debug/di/process.cpp | 3 +++ src/coreclr/debug/di/valuehome.cpp | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/coreclr/debug/di/process.cpp b/src/coreclr/debug/di/process.cpp index 23c00bac733bd8..7786e71a8e0a63 100644 --- a/src/coreclr/debug/di/process.cpp +++ b/src/coreclr/debug/di/process.cpp @@ -662,6 +662,8 @@ HRESULT CordbProcess::GetTargetInfo(IDacDbiInterface::TargetInfo * pTargetInfo) HRESULT hr = S_OK; EX_TRY { + RSLockHolder lockHolder(GetProcessLock()); + if (!m_fHasCachedTargetInfo) { IfFailThrow(GetDAC()->GetTargetInfo(&m_cachedTargetInfo)); @@ -8170,6 +8172,7 @@ HRESULT CordbProcess::GetTargetOpcodeSize(ULONG32 * pcbSize) { case IDacDbiInterface::kArchX86: case IDacDbiInterface::kArchAMD64: + case IDacDbiInterface::kArchWasm: *pcbSize = 1; break; diff --git a/src/coreclr/debug/di/valuehome.cpp b/src/coreclr/debug/di/valuehome.cpp index 09a4bac6dc9397..0552f2efda1469 100644 --- a/src/coreclr/debug/di/valuehome.cpp +++ b/src/coreclr/debug/di/valuehome.cpp @@ -211,7 +211,9 @@ void RegValueHome::SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pCont extendedVal = (SSIZE_T) *(INT64*)newValue.StartAddress(); break; } - default: _ASSERTE(!"bad size"); + default: + _ASSERTE(!"bad size"); + ThrowHR(E_FAIL); } } else @@ -232,7 +234,9 @@ void RegValueHome::SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pCont extendedVal = (SIZE_T) *(UINT64*)newValue.StartAddress(); break; } - default: _ASSERTE(!"bad size"); + default: + _ASSERTE(!"bad size"); + ThrowHR(E_FAIL); } }