summaryrefslogtreecommitdiff
path: root/src/debug/daccess/datatargetadapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug/daccess/datatargetadapter.cpp')
-rw-r--r--src/debug/daccess/datatargetadapter.cpp255
1 files changed, 255 insertions, 0 deletions
diff --git a/src/debug/daccess/datatargetadapter.cpp b/src/debug/daccess/datatargetadapter.cpp
new file mode 100644
index 0000000000..f2a1cc652a
--- /dev/null
+++ b/src/debug/daccess/datatargetadapter.cpp
@@ -0,0 +1,255 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//*****************************************************************************
+// DataTargetAdapter.cpp
+//
+
+//
+// implementation of compatibility adapter for ICLRDataTarget
+//*****************************************************************************
+
+#include "stdafx.h"
+#include "datatargetadapter.h"
+#include <clrdata.h>
+#include "dacimpl.h"
+
+#ifndef IMAGE_FILE_MACHINE_ARM64
+#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian
+#endif
+
+//
+// DataTargetAdaptor ctor
+//
+// Instantiate a DataTargetAdapter over the supplied legacy DataTarget interface.
+// Takes a ref on the supplied interface and releases it in our dtor.
+//
+DataTargetAdapter::DataTargetAdapter(ICLRDataTarget * pLegacyTarget) :
+ m_ref(0),
+ m_pLegacyTarget(pLegacyTarget)
+{
+ m_pLegacyTarget->AddRef();
+}
+
+//
+// DataTargetAdapter dtor
+//
+// Releases the underlying DataTarget interface
+//
+DataTargetAdapter::~DataTargetAdapter()
+{
+ m_pLegacyTarget->Release();
+}
+
+// Standard impl of IUnknown::QueryInterface
+HRESULT STDMETHODCALLTYPE
+DataTargetAdapter::QueryInterface(
+ REFIID interfaceId,
+ PVOID* pInterface)
+{
+ if (interfaceId == IID_IUnknown)
+ {
+ *pInterface = static_cast<IUnknown *>(static_cast<ICorDebugDataTarget *>(this));
+ }
+ else if (interfaceId == IID_ICorDebugDataTarget)
+ {
+ *pInterface = static_cast<ICorDebugDataTarget *>(this);
+ }
+ else if (interfaceId == IID_ICorDebugMutableDataTarget)
+ {
+ // Note that we always implement the mutable interface, even though our underlying target
+ // may return E_NOTIMPL for all the functions on this interface. There is no reliable way
+ // to tell apriori whether an ICLRDataTarget instance supports writing or not.
+ *pInterface = static_cast<ICorDebugMutableDataTarget *>(this);
+ }
+ else
+ {
+ // For ICorDebugDataTarget4 and other interfaces directly implemented by the legacy data target.
+ return m_pLegacyTarget->QueryInterface(interfaceId, pInterface);
+ }
+
+ AddRef();
+ return S_OK;
+}
+
+// Standard impl of IUnknown::AddRef
+ULONG STDMETHODCALLTYPE
+DataTargetAdapter::AddRef()
+{
+ LONG ref = InterlockedIncrement(&m_ref);
+ return ref;
+}
+
+// Standard impl of IUnknown::Release
+ULONG STDMETHODCALLTYPE
+DataTargetAdapter::Release()
+{
+ SUPPORTS_DAC_HOST_ONLY;
+ LONG ref = InterlockedDecrement(&m_ref);
+ if (ref == 0)
+ {
+ delete this;
+ }
+ return ref;
+}
+
+// impl of interface method ICorDebugDataTarget::GetPlatform
+HRESULT STDMETHODCALLTYPE
+DataTargetAdapter::GetPlatform(
+ CorDebugPlatform * pPlatform)
+{
+ SUPPORTS_DAC_HOST_ONLY;
+
+ // Get the target machine type, and assume it's Windows
+ HRESULT hr;
+
+ ULONG32 ulMachineType;
+ IfFailRet(m_pLegacyTarget->GetMachineType(&ulMachineType));
+
+ ULONG32 ulExpectedPointerSize;
+ CorDebugPlatform platform;
+
+ switch(ulMachineType)
+ {
+#ifdef FEATURE_PAL
+ case IMAGE_FILE_MACHINE_I386:
+ ulExpectedPointerSize = 4;
+ platform = CORDB_PLATFORM_POSIX_X86;
+ break;
+
+ case IMAGE_FILE_MACHINE_AMD64:
+ ulExpectedPointerSize = 8;
+ platform = CORDB_PLATFORM_POSIX_AMD64;
+ break;
+
+ case IMAGE_FILE_MACHINE_ARMNT:
+ ulExpectedPointerSize = 4;
+ platform = CORDB_PLATFORM_POSIX_ARM;
+ break;
+
+ case IMAGE_FILE_MACHINE_IA64:
+ case IMAGE_FILE_MACHINE_ARM64:
+ _ASSERTE_MSG(false, "Not supported platform.");
+ return E_NOTIMPL;
+
+#else // FEATURE_PAL
+ case IMAGE_FILE_MACHINE_I386:
+ ulExpectedPointerSize = 4;
+ platform = CORDB_PLATFORM_WINDOWS_X86;
+ break;
+
+ case IMAGE_FILE_MACHINE_AMD64:
+ ulExpectedPointerSize = 8;
+ platform = CORDB_PLATFORM_WINDOWS_AMD64;
+ break;
+
+ case IMAGE_FILE_MACHINE_IA64:
+ ulExpectedPointerSize = 8;
+ platform = CORDB_PLATFORM_WINDOWS_IA64;
+ break;
+
+ case IMAGE_FILE_MACHINE_ARMNT:
+ ulExpectedPointerSize = 4;
+ platform = CORDB_PLATFORM_WINDOWS_ARM;
+ break;
+
+ case IMAGE_FILE_MACHINE_ARM64:
+ ulExpectedPointerSize = 8;
+ platform = CORDB_PLATFORM_WINDOWS_ARM64;
+ break;
+#endif // FEATURE_PAL
+
+ default:
+ // No other platforms are current supported
+ return E_NOTIMPL;
+ }
+
+ // Validate that the target pointer size matches
+ ULONG32 ulPointerSize;
+ IfFailRet(m_pLegacyTarget->GetPointerSize(&ulPointerSize));
+
+ if (ulPointerSize != ulExpectedPointerSize)
+ {
+ return E_UNEXPECTED;
+ }
+
+ // Found a match
+ *pPlatform = platform;
+ return S_OK;
+}
+
+// impl of interface method ICorDebugDataTarget::ReadVirtual
+HRESULT STDMETHODCALLTYPE
+DataTargetAdapter::ReadVirtual(
+ CORDB_ADDRESS address,
+ PBYTE pBuffer,
+ ULONG32 cbRequestSize,
+ ULONG32 * pcbRead)
+{
+ SUPPORTS_DAC_HOST_ONLY;
+ CLRDATA_ADDRESS cdAddr = TO_CDADDR(address);
+ return m_pLegacyTarget->ReadVirtual(cdAddr, pBuffer, cbRequestSize, pcbRead);
+}
+
+// impl of interface method ICorDebugMutableDataTarget::WriteVirtual
+HRESULT STDMETHODCALLTYPE
+DataTargetAdapter::WriteVirtual(
+ CORDB_ADDRESS address,
+ const BYTE * pBuffer,
+ ULONG32 cbRequestSize)
+{
+ SUPPORTS_DAC_HOST_ONLY;
+ CLRDATA_ADDRESS cdAddr = TO_CDADDR(address);
+ ULONG32 cbWritten = 0;
+ HRESULT hr = S_OK;
+
+ hr = m_pLegacyTarget->WriteVirtual(cdAddr, const_cast<BYTE *>(pBuffer), cbRequestSize, &cbWritten);
+
+ if (SUCCEEDED(hr) && cbWritten != cbRequestSize)
+ {
+ // This shouldn't happen - existing data target implementations make writes atomic (eg.
+ // WriteProcessMemory), even though that isn't strictly required by the old interface.
+ // If this does happen, we technically leave the process in an inconsistent state, and we make no
+ // attempt to recover from that here.
+ _ASSERTE_MSG(false, "Legacy data target WriteVirtual partial write - target left in inconsistent state");
+ return HRESULT_FROM_WIN32(ERROR_PARTIAL_COPY);
+ }
+ return hr;
+}
+
+
+// impl of interface method ICorDebugDataTarget::GetThreadContext
+HRESULT STDMETHODCALLTYPE
+DataTargetAdapter::GetThreadContext(
+ DWORD dwThreadID,
+ ULONG32 contextFlags,
+ ULONG32 contextSize,
+ PBYTE pContext)
+{
+ SUPPORTS_DAC_HOST_ONLY;
+ return m_pLegacyTarget->GetThreadContext(dwThreadID, contextFlags, contextSize, pContext);
+}
+
+// impl of interface method ICorDebugMutableDataTarget::SetThreadContext
+HRESULT STDMETHODCALLTYPE
+DataTargetAdapter::SetThreadContext(
+ DWORD dwThreadID,
+ ULONG32 contextSize,
+ const BYTE * pContext)
+{
+ SUPPORTS_DAC_HOST_ONLY;
+ return m_pLegacyTarget->SetThreadContext(dwThreadID, contextSize, const_cast<BYTE *>(pContext));
+}
+
+// implementation of ICorDebugMutableDataTarget::ContinueStatusChanged
+HRESULT STDMETHODCALLTYPE
+DataTargetAdapter::ContinueStatusChanged(
+ DWORD dwThreadId,
+ CORDB_CONTINUE_STATUS continueStatus)
+{
+ SUPPORTS_DAC_HOST_ONLY;
+ // No corresponding API in pre-arrowhead ICLRDataTarget* interfaces.
+ // Note that we briefly had a ICLRDataTarget4 with this API, but this was never released outside the CLR so
+ // all existing implementations should now be gone.
+ return E_NOTIMPL;
+}