summaryrefslogtreecommitdiff
path: root/src/debug/di/module.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug/di/module.cpp')
-rw-r--r--src/debug/di/module.cpp377
1 files changed, 375 insertions, 2 deletions
diff --git a/src/debug/di/module.cpp b/src/debug/di/module.cpp
index 6717e8575f..36cc6f5f9e 100644
--- a/src/debug/di/module.cpp
+++ b/src/debug/di/module.cpp
@@ -3755,7 +3755,269 @@ HRESULT FindNativeInfoInILVariableArray(DWORD
return CORDBG_E_IL_VAR_NOT_AVAILABLE;
} // FindNativeInfoInILVariableArray
-//* ------------------------------------------------------------------------- *
+
+// * ------------------------------------------------------------------------- *
+// * Variable Enum class
+// * ------------------------------------------------------------------------- *
+//-----------------------------------------------------------------------------
+// CordbVariableHome constructor
+// Arguments:
+// Input:
+// pCode - CordbNativeCode instance containing this variable home
+// pNativeVarInfo - native location, lifetime, and index information for
+// this variable
+// isLocal - indicates whether the instance is a local variable,
+// as opposed to an argument
+// index - the argument or slot index
+// Output:
+// fields of the CordbVariableHome instance have been initialized
+//-----------------------------------------------------------------------------
+CordbVariableHome::CordbVariableHome(CordbNativeCode *pCode,
+ const ICorDebugInfo::NativeVarInfo nativeVarInfo,
+ BOOL isLocal,
+ ULONG index) :
+ CordbBase(pCode->GetModule()->GetProcess(), 0)
+{
+ _ASSERTE(pCode != NULL);
+
+ m_pCode.Assign(pCode);
+ m_nativeVarInfo = nativeVarInfo;
+ m_isLocal = isLocal;
+ m_index = index;
+}
+
+CordbVariableHome::~CordbVariableHome()
+{
+ _ASSERTE(this->IsNeutered());
+}
+
+void CordbVariableHome::Neuter()
+{
+ m_pCode.Clear();
+ CordbBase::Neuter();
+}
+
+//-----------------------------------------------------------------------------
+// Public method for IUnknown::QueryInterface.
+// Has standard QI semantics.
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::QueryInterface(REFIID id, void **pInterface)
+{
+ if (id == IID_ICorDebugVariableHome)
+ {
+ *pInterface = static_cast<ICorDebugVariableHome *>(this);
+ }
+ else if (id == IID_IUnknown)
+ {
+ *pInterface = static_cast<IUnknown *>(static_cast<ICorDebugVariableHome *>(this));
+ }
+ else
+ {
+ *pInterface = NULL;
+ return E_NOINTERFACE;
+ }
+
+ ExternalAddRef();
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetCode
+// Public method to get the Code object containing this variable home.
+//
+// Parameters:
+// ppCode - OUT: returns the Code object for this variable home.
+//
+// Returns:
+// S_OK - on success.
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetCode(ICorDebugCode **ppCode)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(ppCode, ICorDebugCode **);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ HRESULT hr = m_pCode->QueryInterface(IID_ICorDebugCode, (LPVOID*)ppCode);
+
+ return hr;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetSlotIndex
+// Public method to get the slot index for this variable home.
+//
+// Parameters:
+// pSlotIndex - OUT: returns the managed slot-index of this variable home.
+//
+// Returns:
+// S_OK - on success
+// E_FAIL - if the variable is not a local variable, but an argument
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetSlotIndex(ULONG32 *pSlotIndex)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pSlotIndex, ULONG32 *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ if (!m_isLocal)
+ {
+ return E_FAIL;
+ }
+ *pSlotIndex = m_index;
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetArgumentIndex
+// Public method to get the slot index for this variable home.
+//
+// Parameters:
+// pSlotIndex - OUT: returns the managed argument-index of this variable home.
+//
+// Returns:
+// S_OK - on success
+// E_FAIL - if the variable is not an argument, but a local variable
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetArgumentIndex(ULONG32 *pArgumentIndex)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pArgumentIndex, ULONG32 *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ if (m_isLocal)
+ {
+ return E_FAIL;
+ }
+ *pArgumentIndex = m_index;
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetLiveRange
+// Public method to get the native range over which this variable is live.
+//
+// Parameters:
+// pStartOffset - OUT: returns the logical offset at which the variable is
+// first live
+// pEndOffset - OUT: returns the logical offset immediately after that at
+// which the variable is last live
+//
+// Returns:
+// S_OK - on success
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetLiveRange(ULONG32 *pStartOffset,
+ ULONG32 *pEndOffset)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pStartOffset, ULONG32 *);
+ VALIDATE_POINTER_TO_OBJECT(pEndOffset, ULONG32 *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ *pStartOffset = m_nativeVarInfo.startOffset;
+ *pEndOffset = m_nativeVarInfo.endOffset;
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetLocationType
+// Public method to get the type of native location for this variable home.
+//
+// Parameters:
+// pLocationType - OUT: the type of native location
+//
+// Returns:
+// S_OK - on success
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetLocationType(VariableLocationType *pLocationType)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pLocationType, VariableLocationType *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ switch (m_nativeVarInfo.loc.vlType)
+ {
+ case ICorDebugInfo::VLT_REG:
+ *pLocationType = VLT_REGISTER;
+ break;
+ case ICorDebugInfo::VLT_STK:
+ *pLocationType = VLT_REGISTER_RELATIVE;
+ break;
+ default:
+ *pLocationType = VLT_INVALID;
+ }
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetRegister
+// Public method to get the register or base register for this variable hom.
+//
+// Parameters:
+// pRegister - OUT: for VLT_REGISTER location types, gives the register.
+// for VLT_REGISTER_RELATIVE location types, gives the base
+// register.
+//
+// Returns:
+// S_OK - on success
+// E_FAIL - for VLT_INVALID location types
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetRegister(CorDebugRegister *pRegister)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pRegister, CorDebugRegister *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ switch (m_nativeVarInfo.loc.vlType)
+ {
+ case ICorDebugInfo::VLT_REG:
+ *pRegister = ConvertRegNumToCorDebugRegister(m_nativeVarInfo.loc.vlReg.vlrReg);
+ break;
+ case ICorDebugInfo::VLT_STK:
+ *pRegister = ConvertRegNumToCorDebugRegister(m_nativeVarInfo.loc.vlStk.vlsBaseReg);
+ break;
+ default:
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetOffset
+// Public method to get the offset from the base register for this variable home.
+//
+// Parameters:
+// pOffset - OUT: gives the offset from the base register
+//
+// Returns:
+// S_OK - on success
+// E_FAIL - for location types other than VLT_REGISTER_RELATIVE
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetOffset(LONG *pOffset)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pOffset, LONG *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ switch (m_nativeVarInfo.loc.vlType)
+ {
+ case ICorDebugInfo::VLT_STK:
+ *pOffset = m_nativeVarInfo.loc.vlStk.vlsOffset;
+ break;
+ default:
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+
+// * ------------------------------------------------------------------------- *
// * Native Code class
// * ------------------------------------------------------------------------- */
@@ -3780,7 +4042,7 @@ CordbNativeCode::CordbNativeCode(CordbFunction * pFunction,
m_fIsInstantiatedGeneric(fIsInstantiatedGeneric != FALSE)
{
_ASSERTE(GetVersion() >= CorDB_DEFAULT_ENC_FUNCTION_VERSION);
-
+
for (CodeBlobRegion region = kHot; region < MAX_REGIONS; ++region)
{
m_rgCodeRegions[region] = pJitData->m_rgCodeRegions[region];
@@ -3805,6 +4067,10 @@ HRESULT CordbNativeCode::QueryInterface(REFIID id, void ** pInterface)
{
*pInterface = static_cast<ICorDebugCode3 *>(this);
}
+ else if (id == IID_ICorDebugCode4)
+ {
+ *pInterface = static_cast<ICorDebugCode4 *>(this);
+ }
else if (id == IID_IUnknown)
{
*pInterface = static_cast<IUnknown *>(static_cast<ICorDebugCode *>(this));
@@ -4111,6 +4377,113 @@ HRESULT CordbNativeCode::GetReturnValueLiveOffset(ULONG32 ILoffset, ULONG32 buff
return hr;
}
+//-----------------------------------------------------------------------------
+// CordbNativeCode::EnumerateVariableHomes
+// Public method to get an enumeration of native variable homes. This may
+// include multiple ICorDebugVariableHomes for the same slot or argument index
+// if they have different homes at different points in the function.
+//
+// Parameters:
+// ppEnum - OUT: returns the enum of variable homes.
+//
+// Returns:
+// HRESULT for success or failure.
+//-----------------------------------------------------------------------------
+HRESULT CordbNativeCode::EnumerateVariableHomes(ICorDebugVariableHomeEnum **ppEnum)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(ppEnum, ICorDebugVariableHomeEnum **);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
+
+ HRESULT hr = S_OK;
+
+ // Get the argument count
+ ULONG argCount = 0;
+ CordbFunction *func = GetFunction();
+ _ASSERTE(func != NULL);
+ IfFailRet(func->GetSig(NULL, &argCount, NULL));
+
+#ifdef _DEBUG
+ // Get the number of locals
+ ULONG localCount = 0;
+ EX_TRY
+ {
+ GetFunction()->GetILCode()->GetLocalVarSig(NULL, &localCount);
+ }
+ EX_CATCH_HRESULT(hr);
+ IfFailRet(hr);
+#endif
+
+ RSSmartPtr<CordbVariableHome> *rsHomes = NULL;
+
+ EX_TRY
+ {
+ CordbProcess *pProcess = GetProcess();
+ _ASSERTE(pProcess != NULL);
+
+ const DacDbiArrayList<ICorDebugInfo::NativeVarInfo> *pOffsetInfoList = m_nativeVarData.GetOffsetInfoList();
+ _ASSERTE(pOffsetInfoList != NULL);
+ DWORD countHomes = 0;
+ for (int i = 0; i < pOffsetInfoList->Count(); i++)
+ {
+ const ICorDebugInfo::NativeVarInfo *pNativeVarInfo = &((*pOffsetInfoList)[i]);
+ _ASSERTE(pNativeVarInfo != NULL);
+
+ // The variable information list can include variables
+ // with special varNumbers representing, for instance, the
+ // parameter types for generic methods. Here we are only
+ // interested in local variables and arguments.
+ if (pNativeVarInfo->varNumber < (DWORD)ICorDebugInfo::MAX_ILNUM)
+ {
+ countHomes++;
+ }
+ }
+ rsHomes = new RSSmartPtr<CordbVariableHome>[countHomes];
+
+ DWORD varHomeInd = 0;
+ for (int i = 0; i < pOffsetInfoList->Count(); i++)
+ {
+ const ICorDebugInfo::NativeVarInfo *pNativeVarInfo = &((*pOffsetInfoList)[i]);
+
+ // Again, only look for native var info representing local
+ // variables and arguments.
+ if (pNativeVarInfo->varNumber < (DWORD)ICorDebugInfo::MAX_ILNUM)
+ {
+ // determine whether this variable home represents and argument or local variable
+ BOOL isLocal = ((ULONG)pNativeVarInfo->varNumber >= argCount);
+
+ // determine the argument-index or slot-index of this variable home
+ ULONG argOrSlotIndex;
+ if (isLocal) {
+ argOrSlotIndex = pNativeVarInfo->varNumber - argCount;
+ _ASSERTE(argOrSlotIndex < localCount);
+ } else {
+ argOrSlotIndex = pNativeVarInfo->varNumber;
+ }
+
+ RSInitHolder<CordbVariableHome> pCVH(new CordbVariableHome(this,
+ (*pOffsetInfoList)[i],
+ isLocal,
+ argOrSlotIndex));
+ pProcess->GetContinueNeuterList()->Add(pProcess, pCVH);
+ _ASSERTE(varHomeInd < countHomes);
+ rsHomes[varHomeInd].Assign(pCVH);
+ pCVH.ClearAndMarkDontNeuter();
+ varHomeInd++;
+ }
+ }
+
+ RSInitHolder<CordbVariableHomeEnumerator> pCDVHE(
+ new CordbVariableHomeEnumerator(GetProcess(), &rsHomes, countHomes));
+ pProcess->GetContinueNeuterList()->Add(pProcess, pCDVHE);
+ pCDVHE.TransferOwnershipExternal(ppEnum);
+ }
+ EX_CATCH_HRESULT(hr);
+
+ return hr;
+}
+
int CordbNativeCode::GetCallInstructionLength(BYTE *ip, ULONG32 count)
{
#if defined(DBG_TARGET_ARM)