TADDR DacGetTargetVtForHostVt(LPCVOID vtHost, bool throwEx) { PVOID* host; ULONG* targ; ULONG i; // The host vtable table exactly parallels the // target vtable table, so just iterate to a match // return the matching entry. host = &g_dacHostVtPtrs.Thread; targ = &g_dacGlobals.Thread__vtAddr; for (i = 0; i < sizeof(g_dacHostVtPtrs) / sizeof(PVOID); i++) { if (*host == vtHost) { return *targ + DacGlobalBase(); } host++; targ++; } if (throwEx) { DacError(E_INVALIDARG); } return 0; }
PWSTR DacGetVtNameW(TADDR targetVtable) { PWSTR pszRet = NULL; ULONG *targ = &g_dacGlobals.Thread__vtAddr; ULONG *targStart = targ; for (ULONG i = 0; i < sizeof(g_dacHostVtPtrs) / sizeof(PVOID); i++) { if (targetVtable == (*targ + DacGlobalBase())) { pszRet = (PWSTR) *(g_dacVtStrings + (targ - targStart)); } targ++; } return pszRet; }
HRESULT DacVirtualUnwind(DWORD threadId, PT_CONTEXT context, PT_KNONVOLATILE_CONTEXT_POINTERS contextPointers) { if (!g_dacImpl) { DacError(E_UNEXPECTED); UNREACHABLE(); } // The DAC code doesn't use these context pointers but zero them out to be safe. if (contextPointers != NULL) { memset(contextPointers, 0, sizeof(T_KNONVOLATILE_CONTEXT_POINTERS)); } HRESULT hr = S_OK; #ifdef FEATURE_DATATARGET4 ReleaseHolder<ICorDebugDataTarget4> dt; hr = g_dacImpl->m_pTarget->QueryInterface(IID_ICorDebugDataTarget4, (void **)&dt); if (SUCCEEDED(hr)) { hr = dt->VirtualUnwind(threadId, sizeof(CONTEXT), (BYTE*)context); } else #endif { SIZE_T baseAddress = DacGlobalBase(); if (baseAddress == 0 || !PAL_VirtualUnwindOutOfProc(context, contextPointers, baseAddress, DacReadAllAdapter)) { hr = E_FAIL; } } return hr; }