NullReferenceException APIs (#7338)
authorSven Boemer <sbomer@gmail.com>
Fri, 14 Oct 2016 21:05:08 +0000 (14:05 -0700)
committerJan Kotas <jkotas@microsoft.com>
Fri, 14 Oct 2016 21:05:08 +0000 (14:05 -0700)
* add typeID APIs
* add variable home API

src/debug/daccess/dacdbiimpl.cpp
src/debug/daccess/dacdbiimpl.h
src/debug/di/module.cpp
src/debug/di/rsenumerator.hpp
src/debug/di/rspriv.h
src/debug/di/rstype.cpp
src/debug/inc/dacdbiinterface.h
src/inc/cordebug.idl
src/pal/prebuilt/idl/cordebug_i.cpp
src/pal/prebuilt/inc/cordebug.h

index cb9c031..26e3d6c 100644 (file)
@@ -2364,10 +2364,12 @@ TypeHandle DacDbiInterfaceImpl::FindLoadedFnptrType(DWORD numTypeArgs, TypeHandl
     // Lookup operations run the class loader in non-load mode.
     ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE();
 
-    // @dbgtodo : Do we need to worry about calling convention here? 
-    return  ClassLoader::LoadFnptrTypeThrowing(0, 
-                                               numTypeArgs, 
-                                               pInst, 
+    // @dbgtodo : Do we need to worry about calling convention here?
+    // LoadFnptrTypeThrowing expects the count of arguments, not
+    // including return value, so we subtract 1 from numTypeArgs.
+    return  ClassLoader::LoadFnptrTypeThrowing(0,
+                                               numTypeArgs - 1,
+                                               pInst,
                                                ClassLoader::DontLoadTypes);
 } // DacDbiInterfaceImpl::FindLoadedFnptrType
 
@@ -6987,6 +6989,21 @@ HRESULT DacDbiInterfaceImpl::GetTypeID(CORDB_ADDRESS dbgObj, COR_TYPEID *pID)
     return hr;
 }
 
+HRESULT DacDbiInterfaceImpl::GetTypeIDForType(VMPTR_TypeHandle vmTypeHandle, COR_TYPEID *pID)
+{
+    DD_ENTER_MAY_THROW;
+
+    _ASSERTE(pID != NULL);
+    _ASSERTE(!vmTypeHandle.IsNull());
+
+    TypeHandle th = TypeHandle::FromPtr(vmTypeHandle.GetDacPtr());
+    PTR_MethodTable pMT = th.GetMethodTable();
+    pID->token1 = pMT.GetAddr();
+    _ASSERTE(pID->token1 != 0);
+    pID->token2 = 0;
+    return S_OK;
+}
+
 HRESULT DacDbiInterfaceImpl::GetObjectFields(COR_TYPEID id, ULONG32 celt, COR_FIELD *layout, ULONG32 *pceltFetched)
 {
     if (layout == NULL || pceltFetched == NULL)
index 56d7b0d..a860723 100644 (file)
@@ -138,11 +138,13 @@ public:
     HRESULT WalkRefs(RefWalkHandle handle, ULONG count, OUT DacGcReference * objects, OUT ULONG *pFetched);
     
     HRESULT GetTypeID(CORDB_ADDRESS obj, COR_TYPEID *pID);
+
+    HRESULT GetTypeIDForType(VMPTR_TypeHandle vmTypeHandle, COR_TYPEID *pID);
     
-       HRESULT GetObjectFields(COR_TYPEID id, ULONG32 celt, COR_FIELD *layout, ULONG32 *pceltFetched);
-       HRESULT GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT *pLayout);
-       HRESULT GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT *pLayout);
-       void GetGCHeapInformation(COR_HEAPINFO * pHeapInfo);
+    HRESULT GetObjectFields(COR_TYPEID id, ULONG32 celt, COR_FIELD *layout, ULONG32 *pceltFetched);
+    HRESULT GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT *pLayout);
+    HRESULT GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT *pLayout);
+    void GetGCHeapInformation(COR_HEAPINFO * pHeapInfo);
     HRESULT GetPEFileMDInternalRW(VMPTR_PEFile vmPEFile, OUT TADDR* pAddrMDInternalRW);
     HRESULT GetReJitInfo(VMPTR_Module vmModule, mdMethodDef methodTk, OUT VMPTR_ReJitInfo* pReJitInfo);
     HRESULT GetReJitInfo(VMPTR_MethodDesc vmMethod, CORDB_ADDRESS codeStartAddress, OUT VMPTR_ReJitInfo* pReJitInfo);
index 6717e85..36cc6f5 100644 (file)
@@ -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)
index eb7a225..84e6194 100644 (file)
@@ -99,8 +99,8 @@ CordbEnumerator<ElemType,
                                                 ElemType **items,
                                                 DWORD countItems) :
 CordbBase(pProcess, 0, enumCordbEnumerator),
-m_nextIndex(0),
-m_countItems(countItems)
+m_countItems(countItems),
+m_nextIndex(0)
 {
     _ASSERTE(items != NULL);
     m_items = *items;
@@ -108,7 +108,7 @@ m_countItems(countItems)
 }
 
 // Destructor
-template< typename ElemType, 
+template< typename ElemType,
           typename ElemPublicType,
           typename EnumInterfaceType,
           ElemPublicType (*GetPublicType)(ElemType)>
index 8537678..bc0ea59 100644 (file)
@@ -85,6 +85,7 @@ class CordbJITILFrame;
 class CordbInternalFrame;
 class CordbContext;
 class CordbThread;
+class CordbVariableHome;
 
 #ifdef FEATURE_INTEROP_DEBUGGING
 class CordbUnmanagedThread;
@@ -1586,7 +1587,7 @@ template< typename ElemType,
           typename ElemPublicType,
           typename EnumInterfaceType,
           ElemPublicType (*GetPublicType)(ElemType)>
-class CordbEnumerator : public CordbBase, EnumInterfaceType
+class CordbEnumerator : public CordbBase, public EnumInterfaceType
 {
 private:
     // the list of items being enumerated over
@@ -1680,6 +1681,11 @@ typedef CordbEnumerator<RsGuidToTypeMapping,
                         ICorDebugGuidToTypeEnum,
                         GuidToTypeMappingConvert > CordbGuidToTypeEnumerator;
 
+typedef CordbEnumerator<RSSmartPtr<CordbVariableHome>,
+                        ICorDebugVariableHome*,
+                        ICorDebugVariableHomeEnum,
+                        QueryInterfaceConvert<RSSmartPtr<CordbVariableHome>, ICorDebugVariableHome> > CordbVariableHomeEnumerator;
+
 // ----------------------------------------------------------------------------
 // Hash table for CordbBase objects.
 // - Uses Internal AddRef/Release (not external)
@@ -2920,7 +2926,7 @@ class CordbProcess :
     public ICorDebugProcess4,
     public ICorDebugProcess5,
     public ICorDebugProcess7,
-       public ICorDebugProcess8,
+    public ICorDebugProcess8,
     public IDacDbiInterface::IAllocator,
     public IDacDbiInterface::IMetaDataLookup,
     public IProcessShimHooks
@@ -4696,7 +4702,7 @@ public:
 // See definition of ICorDebugType for further invariants on types.
 //
 
-class CordbType : public CordbBase, public ICorDebugType
+class CordbType : public CordbBase, public ICorDebugType, public ICorDebugType2
 {
 public:
     CordbType(CordbAppDomain *appdomain, CorElementType ty, unsigned int rank);
@@ -4736,6 +4742,11 @@ public:
     COM_METHOD GetRank(ULONG32 *pnRank);
 
     //-----------------------------------------------------------
+    // ICorDebugType2
+    //-----------------------------------------------------------
+    COM_METHOD GetTypeID(COR_TYPEID *pId);
+    
+    //-----------------------------------------------------------
     // Non-COM members
     //-----------------------------------------------------------
 
@@ -5812,7 +5823,10 @@ private:
  * code, including an optional set of mappings from IL to offsets in the native Code.
  * ------------------------------------------------------------------------- */
 
-class CordbNativeCode : public CordbCode, public ICorDebugCode2, public ICorDebugCode3
+class CordbNativeCode : public CordbCode,
+                        public ICorDebugCode2,
+                        public ICorDebugCode3,
+                        public ICorDebugCode4
 {
 public:
     CordbNativeCode(CordbFunction * pFunction, 
@@ -5853,6 +5867,11 @@ public:
     
 
     //-----------------------------------------------------------
+    // ICorDebugCode4
+    //-----------------------------------------------------------
+    COM_METHOD EnumerateVariableHomes(ICorDebugVariableHomeEnum **ppEnum);
+    
+    //-----------------------------------------------------------
     // Internal members
     //-----------------------------------------------------------
 
@@ -8539,6 +8558,63 @@ private:
 typedef enum {kUnboxed, kBoxed} BoxedValue;
 #define EMPTY_BUFFER TargetBuffer(PTR_TO_CORDB_ADDRESS((void *)NULL), 0)
 
+/* ------------------------------------------------------------------------- *
+ * Variable Home class
+ * ------------------------------------------------------------------------- */
+class CordbVariableHome : public CordbBase, public ICorDebugVariableHome
+{
+public:
+    CordbVariableHome(CordbNativeCode *pCode,
+                      const ICorDebugInfo::NativeVarInfo nativeVarInfo,
+                      BOOL isLoc,
+                      ULONG index);
+    ~CordbVariableHome();
+    virtual void Neuter();
+
+#ifdef _DEBUG
+    virtual const char * DbgGetName() { return "CordbVariableHome"; }
+#endif
+    
+    //-----------------------------------------------------------
+    // IUnknown
+    //-----------------------------------------------------------
+    ULONG STDMETHODCALLTYPE AddRef()
+    {
+        return (BaseAddRef());
+    }
+    ULONG STDMETHODCALLTYPE Release()
+    {
+        return (BaseRelease());
+    }
+
+    COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
+    
+    //-----------------------------------------------------------
+    // ICorDebugVariableHome
+    //-----------------------------------------------------------
+    
+    COM_METHOD GetCode(ICorDebugCode **ppCode);
+    
+    COM_METHOD GetSlotIndex(ULONG32 *pSlotIndex);
+
+    COM_METHOD GetArgumentIndex(ULONG32* pArgumentIndex);
+
+    COM_METHOD GetLiveRange(ULONG32* pStartOffset,
+                            ULONG32 *pEndOffset);
+    
+    COM_METHOD GetLocationType(VariableLocationType *pLocationType);
+
+    COM_METHOD GetRegister(CorDebugRegister *pRegister);
+    
+    COM_METHOD GetOffset(LONG *pOffset);
+private:
+    RSSmartPtr<CordbNativeCode> m_pCode;
+    ICorDebugInfo::NativeVarInfo m_nativeVarInfo;
+    BOOL m_isLocal;
+    ULONG m_index;
+};
+
+
 // for an inheritance graph of the ICDValue types, // See file:./ICorDebugValueTypes.vsd for a diagram of the types.  
 /* ------------------------------------------------------------------------- *
  * Value class
index b183fdf..e537613 100644 (file)
@@ -276,6 +276,8 @@ HRESULT CordbType::QueryInterface(REFIID id, void **pInterface)
 {
     if (id == IID_ICorDebugType)
         *pInterface = static_cast<ICorDebugType*>(this);
+    else if (id == IID_ICorDebugType2)
+        *pInterface = static_cast<ICorDebugType2*>(this);
     else if (id == IID_IUnknown)
         *pInterface = static_cast<IUnknown*>(static_cast<ICorDebugType*>(this));
     else
@@ -2280,6 +2282,126 @@ HRESULT CordbType::GetBase(ICorDebugType ** ppType)
     return hr;
 }
 
+//-----------------------------------------------------------------------------
+// CordbType::GetTypeID
+// Method to get the COR_TYPEID corresponding to this CordbType.
+//
+// Parameters:
+//   pId - OUT: gives the COR_TYPEID for this CordbType
+//
+// Returns:
+//   S_OK if succeeded.
+//   CORDBG_E_CLASS_NOT_LOADED if the type which this CordbType represents has
+//       not been loaded in the runtime.
+//  E_POINTER if pId is NULL
+//  CORDBG_E_UNSUPPORTED for unsupported types.
+//
+HRESULT CordbType::GetTypeID(COR_TYPEID *pId)
+{
+    LOG((LF_CORDB, LL_INFO1000, "GetTypeID\n"));
+    if (pId == NULL)
+        return E_POINTER;
+    
+    HRESULT hr = S_OK;
+
+    PUBLIC_API_ENTRY(this);
+    RSLockHolder stopGoLock(GetProcess()->GetStopGoLock());
+    RSLockHolder procLock(GetProcess()->GetProcessLock());
+
+    EX_TRY
+    {
+        hr = Init(FALSE);
+        IfFailThrow(hr);
+
+        VMPTR_TypeHandle vmTypeHandle;
+            
+        CorElementType et = GetElementType();
+        switch (et)
+        {
+        case ELEMENT_TYPE_OBJECT:
+        case ELEMENT_TYPE_VOID:
+        case ELEMENT_TYPE_BOOLEAN:
+        case ELEMENT_TYPE_CHAR:
+        case ELEMENT_TYPE_I1:
+        case ELEMENT_TYPE_U1:
+        case ELEMENT_TYPE_I2:
+        case ELEMENT_TYPE_U2:
+        case ELEMENT_TYPE_I4:
+        case ELEMENT_TYPE_U4:
+        case ELEMENT_TYPE_I8:
+        case ELEMENT_TYPE_U8:
+        case ELEMENT_TYPE_R4:
+        case ELEMENT_TYPE_R8:
+        case ELEMENT_TYPE_STRING:
+        case ELEMENT_TYPE_TYPEDBYREF:
+        case ELEMENT_TYPE_I:
+        case ELEMENT_TYPE_U:
+            {
+                mdTypeDef mdToken;
+                VMPTR_Module vmModule = VMPTR_Module::NullPtr();
+                VMPTR_DomainFile vmDomainFile = VMPTR_DomainFile::NullPtr();
+
+                // get module and token of the simple type
+                GetProcess()->GetDAC()->GetSimpleType(GetAppDomain()->GetADToken(),
+                                                      et,
+                                                      &mdToken,
+                                                      &vmModule,
+                                                      &vmDomainFile);
+                
+                vmTypeHandle = GetProcess()->GetDAC()->GetTypeHandle(vmModule, mdToken);
+            }
+            break;
+        case ELEMENT_TYPE_ARRAY:
+        case ELEMENT_TYPE_SZARRAY:
+            {
+                LOG((LF_CORDB, LL_INFO1000, "GetTypeID: parameterized type\n"));
+                if (m_typeHandleExact.IsNull())
+                {
+                    hr = InitInstantiationTypeHandle(FALSE);
+                    IfFailThrow(hr);
+                }
+                vmTypeHandle = m_typeHandleExact;
+            }
+            break;
+        case ELEMENT_TYPE_CLASS:
+            {
+                ICorDebugClass *pICDClass = NULL;
+                hr = GetClass(&pICDClass);
+                IfFailThrow(hr);
+                CordbClass *pClass = (CordbClass*)pICDClass;
+                _ASSERTE(pClass != NULL);
+                
+                if (pClass->HasTypeParams())
+                {
+                    vmTypeHandle = m_typeHandleExact;
+                }
+                else
+                {
+                    mdTypeDef mdToken;
+                    hr = pClass->GetToken(&mdToken);
+                    IfFailThrow(hr);
+                    
+                    VMPTR_Module vmModule = GetModule();
+                    vmTypeHandle = GetProcess()->GetDAC()->GetTypeHandle(vmModule, mdToken);
+                }
+            }
+            break;
+        case ELEMENT_TYPE_PTR:
+        case ELEMENT_TYPE_BYREF:
+        case ELEMENT_TYPE_FNPTR:
+            IfFailThrow(CORDBG_E_UNSUPPORTED);
+        default:
+            _ASSERTE(!"unexpected element type!");
+            IfFailThrow(CORDBG_E_UNSUPPORTED);
+            break;
+        }
+
+        GetProcess()->GetDAC()->GetTypeIDForType(vmTypeHandle, pId);
+    }
+    EX_CATCH_HRESULT(hr);
+
+    return hr;
+}
 
 //-----------------------------------------------------------------------------
 // Get rich field information given a token.
index fe58724..e61e240 100644 (file)
@@ -2508,17 +2508,20 @@ public:
     virtual
     HRESULT GetTypeID(CORDB_ADDRESS obj, COR_TYPEID * pType) = 0;
 
-       virtual
-       HRESULT GetObjectFields(COR_TYPEID id, ULONG32 celt, OUT COR_FIELD * layout, OUT ULONG32 * pceltFetched) = 0;
-
-       virtual
-       HRESULT GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT * pLayout) = 0;
-       
-       virtual
-       HRESULT GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT * pLayout) = 0;
-       
-       virtual
-       void GetGCHeapInformation(OUT COR_HEAPINFO * pHeapInfo) = 0;
+    virtual
+    HRESULT GetTypeIDForType(VMPTR_TypeHandle vmTypeHandle, COR_TYPEID *pId) = 0;
+    
+    virtual
+    HRESULT GetObjectFields(COR_TYPEID id, ULONG32 celt, OUT COR_FIELD * layout, OUT ULONG32 * pceltFetched) = 0;
+    
+    virtual
+    HRESULT GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT * pLayout) = 0;
+    
+    virtual
+    HRESULT GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT * pLayout) = 0;
+    
+    virtual
+    void GetGCHeapInformation(OUT COR_HEAPINFO * pHeapInfo) = 0;
 
     // If a PEFile has an RW capable IMDInternalImport, this returns the address of the MDInternalRW
     // object which implements it.
index 49b8acc..093b893 100644 (file)
@@ -177,6 +177,7 @@ interface ICorDebugTypeEnum;
 interface ICorDebugCodeEnum;
 interface ICorDebugFrameEnum;
 interface ICorDebugValueEnum;
+interface ICorDebugVariableHomeEnum;
 interface ICorDebugAppDomainEnum;
 interface ICorDebugAssemblyEnum;
 interface ICorDebugBlockingObjectEnum;
@@ -5594,6 +5595,23 @@ interface ICorDebugCode3 : IUnknown
                                      [out, size_is(bufferSize), length_is(*pFetched)] ULONG32 pOffsets[]);
 };
 
+[
+    object,
+    local,
+    uuid(18221fa4-20cb-40fa-b19d-9f91c4fa8c14),
+    pointer_default(unique)
+]
+interface ICorDebugCode4 : IUnknown
+{
+    /*
+     * EnumerateVariableHomes - gives an enum for local variables and arguments
+     * in the function.
+     * This may include multiple ICorDebugVariableHomes for the same slot or
+     * argument index if they have different homes at different points in the
+     * function.
+     */
+    HRESULT EnumerateVariableHomes([out] ICorDebugVariableHomeEnum **ppEnum);
+}
 
 [
     object,
@@ -6488,8 +6506,79 @@ interface ICorDebugArrayValue : ICorDebugHeapValue
                                  [out] ICorDebugValue **ppValue);
 };
 
+[
+    object,
+    local,
+    uuid(50847b8d-f43f-41b0-924c-6383a5f2278b),
+    pointer_default(unique)
+]
+interface ICorDebugVariableHome : IUnknown
+{
+    /*
+     * GetCode - gives the ICorDebugCode instance containing this
+     * ICorDebugVariableHome.
+     */
+    HRESULT GetCode([out] ICorDebugCode **ppCode);
+    /*
+     * GetSlotIndex - gives the managed slot-index of a local variable.
+     * The slot-index can be used to retrieve the metadata for this local.
+     * Returns E_FAIL if the variable is a function argument.
+     */
+    HRESULT GetSlotIndex([out] ULONG32 *pSlotIndex);
+    
+    /*
+     * GetArgumentIndex - gives the argument index of a function argument.
+     * The argument index can be used to retrieve the metadata for this
+     * argument.
+     * Returns E_FAIL if the variable is a local variable.
+     */
+    HRESULT GetArgumentIndex([out] ULONG32* pArgumentIndex);
 
-/*
+    /*
+     * GetLiveRange - gives the native range over which this variable is live.
+     * pStartOffset is the logical offset at which the variable is first live.
+     * pEndOffset is the logical offset immediately after that at which the
+     * variable is last live.
+     */
+    HRESULT GetLiveRange([out] ULONG32* pStartOffset,
+                         [out] ULONG32 *pEndOffset);
+
+    typedef enum VariableLocationType
+    {
+        VLT_REGISTER,             // variable is in a register
+        VLT_REGISTER_RELATIVE,    // variable is in a register-relative memory
+                                  // location
+        VLT_INVALID
+    } VariableLocationType;
+    
+    /*
+     * GetLocationType - gives the type of native location. See
+     * VariableLocationType.
+     * Returns VLT_INVALID if the variable is not stored in a register or in a
+     * register-relative memory location.
+     */
+    HRESULT GetLocationType([out] VariableLocationType *pLocationType);
+
+    /*
+     * GetRegister - gives the register containing the variables with location
+     * type VLT_REGISTER, and the base register for variables with location
+     * type VLT_REGISTER_RELATIVE.
+     * Returns E_FAIL if the variable is not in a register or in a
+     * register-relative location.
+     */
+    HRESULT GetRegister([out] CorDebugRegister *pRegister);
+    
+    /*
+     * GetOffset - gives the offset from the base register for a variable.
+     * Returns E_FAIL if the variable is not in a register-relative memory
+     * location.
+     */
+    HRESULT GetOffset([out] LONG *pOffset);
+}
+
+
+
+/* 
  * ICorDebugHandleValue represents a reference value that the debugger has
  * explicitly created a GC handle to. It does not represent GC Handles in the debuggee process,
 
@@ -6802,6 +6891,28 @@ interface ICorDebugValueEnum : ICorDebugEnum
 [
     object,
     local,
+    uuid(e76b7a57-4f7a-4309-85a7-5d918c3deaf7),
+    pointer_default(unique)
+]
+interface ICorDebugVariableHomeEnum : ICorDebugEnum
+{
+    /*
+     * Next - gives the specified number of ICorDebugVariableHome instances from
+     * the enumeration, starting at the current position.
+     * celt is the number of requested instances.
+     * pceltFetched is the number of instances retrieved.
+     * returns S_FALSE if the actual number of instances retrieved is smaller
+     * than the number of instances requested.
+     */
+    HRESULT Next([in] ULONG celt,
+                 [out, size_is(celt), length_is(*pceltFetched)]
+                     ICorDebugVariableHome *homes[],
+                 [out] ULONG *pceltFetched);
+};
+    
+[
+    object,
+    local,
     uuid(55E96461-9645-45e4-A2FF-0367877ABCDE),
     pointer_default(unique)
 ]
@@ -6951,6 +7062,28 @@ interface ICorDebugType : IUnknown
 };
 
 
+[
+    object,
+    local,
+    uuid(e6e91d79-693d-48bc-b417-8284b4f10fb5),
+    pointer_default(unique)
+]
+interface ICorDebugType2 : IUnknown
+{
+    /*
+     * GetTypeID - gives a COR_TYPEID for the ICorDebugType. This
+     * provides a mapping from the ICorDebugType, which represents a
+     * type that may or may not have been loaded into the runtime, to
+     * a COR_TYPEID, which serves as an opaque handle identifying a
+     * type loaded into the runtime. When the type that the
+     * ICorDebugType represents has not yet been loaded, this returns
+     * CORDBG_E_CLASS_NOT_LOADED. Returns CORDBG_E_UNSUPPORTED for
+     * unsupported types.
+     */
+    HRESULT GetTypeID([out] COR_TYPEID *id);
+};
+
+
 /* ------------------------------------------------------------------------- *
  * DEPRECATED
  *
index e3c8d2e..dd69e57 100644 (file)
@@ -5,11 +5,11 @@
 /* link this file in with the server and any clients */
 
 
- /* File created by MIDL compiler version 8.00.0613 */
-/* at Mon Jan 18 19:14:07 2038
+ /* File created by MIDL compiler version 8.00.0603 */
+/* at Fri Sep 23 15:43:16 2016
  */
-/* Compiler settings for C:/ssd/coreclr/src/inc/cordebug.idl:
-    Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.061
+/* Compiler settings for cordebug.idl:
+    Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.060
     protocol : dce , ms_ext, c_ext, robust
     error checks: allocation ref bounds_check enum stub_data 
     VC __declspec() decoration level: 
@@ -304,6 +304,9 @@ MIDL_DEFINE_GUID(IID, IID_ICorDebugCode2,0x5F696509,0x452F,0x4436,0xA3,0xFE,0x4D
 MIDL_DEFINE_GUID(IID, IID_ICorDebugCode3,0xD13D3E88,0xE1F2,0x4020,0xAA,0x1D,0x3D,0x16,0x2D,0xCB,0xE9,0x66);
 
 
+MIDL_DEFINE_GUID(IID, IID_ICorDebugCode4,0x18221fa4,0x20cb,0x40fa,0xb1,0x9d,0x9f,0x91,0xc4,0xfa,0x8c,0x14);
+
+
 MIDL_DEFINE_GUID(IID, IID_ICorDebugILCode,0x598D46C2,0xC877,0x42A7,0x89,0xD2,0x3D,0x0C,0x7F,0x1C,0x12,0x64);
 
 
@@ -361,6 +364,9 @@ MIDL_DEFINE_GUID(IID, IID_ICorDebugStringValue,0xCC7BCAFD,0x8A68,0x11d2,0x98,0x3
 MIDL_DEFINE_GUID(IID, IID_ICorDebugArrayValue,0x0405B0DF,0xA660,0x11d2,0xBD,0x02,0x00,0x00,0xF8,0x08,0x49,0xBD);
 
 
+MIDL_DEFINE_GUID(IID, IID_ICorDebugVariableHome,0x50847b8d,0xf43f,0x41b0,0x92,0x4c,0x63,0x83,0xa5,0xf2,0x27,0x8b);
+
+
 MIDL_DEFINE_GUID(IID, IID_ICorDebugHandleValue,0x029596E8,0x276B,0x46a1,0x98,0x21,0x73,0x2E,0x96,0xBB,0xB0,0x0B);
 
 
@@ -397,6 +403,9 @@ MIDL_DEFINE_GUID(IID, IID_ICorDebugModuleEnum,0xCC7BCB09,0x8A68,0x11d2,0x98,0x3C
 MIDL_DEFINE_GUID(IID, IID_ICorDebugValueEnum,0xCC7BCB0A,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
 
 
+MIDL_DEFINE_GUID(IID, IID_ICorDebugVariableHomeEnum,0xe76b7a57,0x4f7a,0x4309,0x85,0xa7,0x5d,0x91,0x8c,0x3d,0xea,0xf7);
+
+
 MIDL_DEFINE_GUID(IID, IID_ICorDebugCodeEnum,0x55E96461,0x9645,0x45e4,0xA2,0xFF,0x03,0x67,0x87,0x7A,0xBC,0xDE);
 
 
@@ -406,6 +415,9 @@ MIDL_DEFINE_GUID(IID, IID_ICorDebugTypeEnum,0x10F27499,0x9DF2,0x43ce,0x83,0x33,0
 MIDL_DEFINE_GUID(IID, IID_ICorDebugType,0xD613F0BB,0xACE1,0x4c19,0xBD,0x72,0xE4,0xC0,0x8D,0x5D,0xA7,0xF5);
 
 
+MIDL_DEFINE_GUID(IID, IID_ICorDebugType2,0xe6e91d79,0x693d,0x48bc,0xb4,0x17,0x82,0x84,0xb4,0xf1,0x0f,0xb5);
+
+
 MIDL_DEFINE_GUID(IID, IID_ICorDebugErrorInfoEnum,0xF0E18809,0x72B5,0x11d2,0x97,0x6F,0x00,0xA0,0xC9,0xB4,0xD5,0x0C);
 
 
index a5a5cf2..3931040 100644 (file)
@@ -4,9 +4,9 @@
 
 
  /* File created by MIDL compiler version 8.00.0603 */
-/* at Fri Jul 15 18:01:08 2016
+/* at Fri Sep 23 15:43:16 2016
  */
-/* Compiler settings for E:/git/coreclr/src/inc/cordebug.idl:
+/* Compiler settings for cordebug.idl:
     Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0603 
     protocol : dce , ms_ext, c_ext, robust
     error checks: allocation ref bounds_check enum stub_data 
@@ -598,6 +598,13 @@ typedef interface ICorDebugCode3 ICorDebugCode3;
 #endif         /* __ICorDebugCode3_FWD_DEFINED__ */
 
 
+#ifndef __ICorDebugCode4_FWD_DEFINED__
+#define __ICorDebugCode4_FWD_DEFINED__
+typedef interface ICorDebugCode4 ICorDebugCode4;
+
+#endif         /* __ICorDebugCode4_FWD_DEFINED__ */
+
+
 #ifndef __ICorDebugILCode_FWD_DEFINED__
 #define __ICorDebugILCode_FWD_DEFINED__
 typedef interface ICorDebugILCode ICorDebugILCode;
@@ -731,6 +738,13 @@ typedef interface ICorDebugArrayValue ICorDebugArrayValue;
 #endif         /* __ICorDebugArrayValue_FWD_DEFINED__ */
 
 
+#ifndef __ICorDebugVariableHome_FWD_DEFINED__
+#define __ICorDebugVariableHome_FWD_DEFINED__
+typedef interface ICorDebugVariableHome ICorDebugVariableHome;
+
+#endif         /* __ICorDebugVariableHome_FWD_DEFINED__ */
+
+
 #ifndef __ICorDebugHandleValue_FWD_DEFINED__
 #define __ICorDebugHandleValue_FWD_DEFINED__
 typedef interface ICorDebugHandleValue ICorDebugHandleValue;
@@ -815,6 +829,13 @@ typedef interface ICorDebugValueEnum ICorDebugValueEnum;
 #endif         /* __ICorDebugValueEnum_FWD_DEFINED__ */
 
 
+#ifndef __ICorDebugVariableHomeEnum_FWD_DEFINED__
+#define __ICorDebugVariableHomeEnum_FWD_DEFINED__
+typedef interface ICorDebugVariableHomeEnum ICorDebugVariableHomeEnum;
+
+#endif         /* __ICorDebugVariableHomeEnum_FWD_DEFINED__ */
+
+
 #ifndef __ICorDebugCodeEnum_FWD_DEFINED__
 #define __ICorDebugCodeEnum_FWD_DEFINED__
 typedef interface ICorDebugCodeEnum ICorDebugCodeEnum;
@@ -836,6 +857,13 @@ typedef interface ICorDebugType ICorDebugType;
 #endif         /* __ICorDebugType_FWD_DEFINED__ */
 
 
+#ifndef __ICorDebugType2_FWD_DEFINED__
+#define __ICorDebugType2_FWD_DEFINED__
+typedef interface ICorDebugType2 ICorDebugType2;
+
+#endif         /* __ICorDebugType2_FWD_DEFINED__ */
+
+
 #ifndef __ICorDebugErrorInfoEnum_FWD_DEFINED__
 #define __ICorDebugErrorInfoEnum_FWD_DEFINED__
 typedef interface ICorDebugErrorInfoEnum ICorDebugErrorInfoEnum;
@@ -1321,6 +1349,7 @@ enum CorDebugNGENPolicy
 
 
 
+
 #pragma warning(pop)
 typedef ULONG64 CORDB_ADDRESS;
 
@@ -12423,6 +12452,86 @@ EXTERN_C const IID IID_ICorDebugCode3;
 #endif         /* __ICorDebugCode3_INTERFACE_DEFINED__ */
 
 
+#ifndef __ICorDebugCode4_INTERFACE_DEFINED__
+#define __ICorDebugCode4_INTERFACE_DEFINED__
+
+/* interface ICorDebugCode4 */
+/* [unique][uuid][local][object] */ 
+
+
+EXTERN_C const IID IID_ICorDebugCode4;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+    
+    MIDL_INTERFACE("18221fa4-20cb-40fa-b19d-9f91c4fa8c14")
+    ICorDebugCode4 : public IUnknown
+    {
+    public:
+        virtual HRESULT STDMETHODCALLTYPE EnumerateVariableHomes( 
+            /* [out] */ ICorDebugVariableHomeEnum **ppEnum) = 0;
+        
+    };
+    
+    
+#else  /* C style interface */
+
+    typedef struct ICorDebugCode4Vtbl
+    {
+        BEGIN_INTERFACE
+        
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
+            ICorDebugCode4 * This,
+            /* [in] */ REFIID riid,
+            /* [annotation][iid_is][out] */ 
+            _COM_Outptr_  void **ppvObject);
+        
+        ULONG ( STDMETHODCALLTYPE *AddRef )( 
+            ICorDebugCode4 * This);
+        
+        ULONG ( STDMETHODCALLTYPE *Release )( 
+            ICorDebugCode4 * This);
+        
+        HRESULT ( STDMETHODCALLTYPE *EnumerateVariableHomes )( 
+            ICorDebugCode4 * This,
+            /* [out] */ ICorDebugVariableHomeEnum **ppEnum);
+        
+        END_INTERFACE
+    } ICorDebugCode4Vtbl;
+
+    interface ICorDebugCode4
+    {
+        CONST_VTBL struct ICorDebugCode4Vtbl *lpVtbl;
+    };
+
+    
+
+#ifdef COBJMACROS
+
+
+#define ICorDebugCode4_QueryInterface(This,riid,ppvObject)     \
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 
+
+#define ICorDebugCode4_AddRef(This)    \
+    ( (This)->lpVtbl -> AddRef(This) ) 
+
+#define ICorDebugCode4_Release(This)   \
+    ( (This)->lpVtbl -> Release(This) ) 
+
+
+#define ICorDebugCode4_EnumerateVariableHomes(This,ppEnum)     \
+    ( (This)->lpVtbl -> EnumerateVariableHomes(This,ppEnum) ) 
+
+#endif /* COBJMACROS */
+
+
+#endif         /* C style interface */
+
+
+
+
+#endif         /* __ICorDebugCode4_INTERFACE_DEFINED__ */
+
+
 #ifndef __ICorDebugILCode_INTERFACE_DEFINED__
 #define __ICorDebugILCode_INTERFACE_DEFINED__
 
@@ -14382,15 +14491,15 @@ EXTERN_C const IID IID_ICorDebugBoxValue;
 #endif         /* __ICorDebugBoxValue_INTERFACE_DEFINED__ */
 
 
-/* interface __MIDL_itf_cordebug_0000_0095 */
+/* interface __MIDL_itf_cordebug_0000_0096 */
 /* [local] */ 
 
 #pragma warning(push)
 #pragma warning(disable:28718) 
 
 
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0095_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0095_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_s_ifspec;
 
 #ifndef __ICorDebugStringValue_INTERFACE_DEFINED__
 #define __ICorDebugStringValue_INTERFACE_DEFINED__
@@ -14530,14 +14639,14 @@ EXTERN_C const IID IID_ICorDebugStringValue;
 #endif         /* __ICorDebugStringValue_INTERFACE_DEFINED__ */
 
 
-/* interface __MIDL_itf_cordebug_0000_0096 */
+/* interface __MIDL_itf_cordebug_0000_0097 */
 /* [local] */ 
 
 #pragma warning(pop)
 
 
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0097_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0097_v0_0_s_ifspec;
 
 #ifndef __ICorDebugArrayValue_INTERFACE_DEFINED__
 #define __ICorDebugArrayValue_INTERFACE_DEFINED__
@@ -14743,6 +14852,156 @@ EXTERN_C const IID IID_ICorDebugArrayValue;
 #endif         /* __ICorDebugArrayValue_INTERFACE_DEFINED__ */
 
 
+#ifndef __ICorDebugVariableHome_INTERFACE_DEFINED__
+#define __ICorDebugVariableHome_INTERFACE_DEFINED__
+
+/* interface ICorDebugVariableHome */
+/* [unique][uuid][local][object] */ 
+
+typedef 
+enum VariableLocationType
+    {
+        VLT_REGISTER   = 0,
+        VLT_REGISTER_RELATIVE  = ( VLT_REGISTER + 1 ) ,
+        VLT_INVALID    = ( VLT_REGISTER_RELATIVE + 1 ) 
+    }  VariableLocationType;
+
+
+EXTERN_C const IID IID_ICorDebugVariableHome;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+    
+    MIDL_INTERFACE("50847b8d-f43f-41b0-924c-6383a5f2278b")
+    ICorDebugVariableHome : public IUnknown
+    {
+    public:
+        virtual HRESULT STDMETHODCALLTYPE GetCode( 
+            /* [out] */ ICorDebugCode **ppCode) = 0;
+        
+        virtual HRESULT STDMETHODCALLTYPE GetSlotIndex( 
+            /* [out] */ ULONG32 *pSlotIndex) = 0;
+        
+        virtual HRESULT STDMETHODCALLTYPE GetArgumentIndex( 
+            /* [out] */ ULONG32 *pArgumentIndex) = 0;
+        
+        virtual HRESULT STDMETHODCALLTYPE GetLiveRange( 
+            /* [out] */ ULONG32 *pStartOffset,
+            /* [out] */ ULONG32 *pEndOffset) = 0;
+        
+        virtual HRESULT STDMETHODCALLTYPE GetLocationType( 
+            /* [out] */ VariableLocationType *pLocationType) = 0;
+        
+        virtual HRESULT STDMETHODCALLTYPE GetRegister( 
+            /* [out] */ CorDebugRegister *pRegister) = 0;
+        
+        virtual HRESULT STDMETHODCALLTYPE GetOffset( 
+            /* [out] */ LONG *pOffset) = 0;
+        
+    };
+    
+    
+#else  /* C style interface */
+
+    typedef struct ICorDebugVariableHomeVtbl
+    {
+        BEGIN_INTERFACE
+        
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
+            ICorDebugVariableHome * This,
+            /* [in] */ REFIID riid,
+            /* [annotation][iid_is][out] */ 
+            _COM_Outptr_  void **ppvObject);
+        
+        ULONG ( STDMETHODCALLTYPE *AddRef )( 
+            ICorDebugVariableHome * This);
+        
+        ULONG ( STDMETHODCALLTYPE *Release )( 
+            ICorDebugVariableHome * This);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetCode )( 
+            ICorDebugVariableHome * This,
+            /* [out] */ ICorDebugCode **ppCode);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetSlotIndex )( 
+            ICorDebugVariableHome * This,
+            /* [out] */ ULONG32 *pSlotIndex);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetArgumentIndex )( 
+            ICorDebugVariableHome * This,
+            /* [out] */ ULONG32 *pArgumentIndex);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetLiveRange )( 
+            ICorDebugVariableHome * This,
+            /* [out] */ ULONG32 *pStartOffset,
+            /* [out] */ ULONG32 *pEndOffset);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetLocationType )( 
+            ICorDebugVariableHome * This,
+            /* [out] */ VariableLocationType *pLocationType);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetRegister )( 
+            ICorDebugVariableHome * This,
+            /* [out] */ CorDebugRegister *pRegister);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetOffset )( 
+            ICorDebugVariableHome * This,
+            /* [out] */ LONG *pOffset);
+        
+        END_INTERFACE
+    } ICorDebugVariableHomeVtbl;
+
+    interface ICorDebugVariableHome
+    {
+        CONST_VTBL struct ICorDebugVariableHomeVtbl *lpVtbl;
+    };
+
+    
+
+#ifdef COBJMACROS
+
+
+#define ICorDebugVariableHome_QueryInterface(This,riid,ppvObject)      \
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 
+
+#define ICorDebugVariableHome_AddRef(This)     \
+    ( (This)->lpVtbl -> AddRef(This) ) 
+
+#define ICorDebugVariableHome_Release(This)    \
+    ( (This)->lpVtbl -> Release(This) ) 
+
+
+#define ICorDebugVariableHome_GetCode(This,ppCode)     \
+    ( (This)->lpVtbl -> GetCode(This,ppCode) ) 
+
+#define ICorDebugVariableHome_GetSlotIndex(This,pSlotIndex)    \
+    ( (This)->lpVtbl -> GetSlotIndex(This,pSlotIndex) ) 
+
+#define ICorDebugVariableHome_GetArgumentIndex(This,pArgumentIndex)    \
+    ( (This)->lpVtbl -> GetArgumentIndex(This,pArgumentIndex) ) 
+
+#define ICorDebugVariableHome_GetLiveRange(This,pStartOffset,pEndOffset)       \
+    ( (This)->lpVtbl -> GetLiveRange(This,pStartOffset,pEndOffset) ) 
+
+#define ICorDebugVariableHome_GetLocationType(This,pLocationType)      \
+    ( (This)->lpVtbl -> GetLocationType(This,pLocationType) ) 
+
+#define ICorDebugVariableHome_GetRegister(This,pRegister)      \
+    ( (This)->lpVtbl -> GetRegister(This,pRegister) ) 
+
+#define ICorDebugVariableHome_GetOffset(This,pOffset)  \
+    ( (This)->lpVtbl -> GetOffset(This,pOffset) ) 
+
+#endif /* COBJMACROS */
+
+
+#endif         /* C style interface */
+
+
+
+
+#endif         /* __ICorDebugVariableHome_INTERFACE_DEFINED__ */
+
+
 #ifndef __ICorDebugHandleValue_INTERFACE_DEFINED__
 #define __ICorDebugHandleValue_INTERFACE_DEFINED__
 
@@ -16154,6 +16413,118 @@ EXTERN_C const IID IID_ICorDebugValueEnum;
 #endif         /* __ICorDebugValueEnum_INTERFACE_DEFINED__ */
 
 
+#ifndef __ICorDebugVariableHomeEnum_INTERFACE_DEFINED__
+#define __ICorDebugVariableHomeEnum_INTERFACE_DEFINED__
+
+/* interface ICorDebugVariableHomeEnum */
+/* [unique][uuid][local][object] */ 
+
+
+EXTERN_C const IID IID_ICorDebugVariableHomeEnum;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+    
+    MIDL_INTERFACE("e76b7a57-4f7a-4309-85a7-5d918c3deaf7")
+    ICorDebugVariableHomeEnum : public ICorDebugEnum
+    {
+    public:
+        virtual HRESULT STDMETHODCALLTYPE Next( 
+            /* [in] */ ULONG celt,
+            /* [length_is][size_is][out] */ ICorDebugVariableHome *homes[  ],
+            /* [out] */ ULONG *pceltFetched) = 0;
+        
+    };
+    
+    
+#else  /* C style interface */
+
+    typedef struct ICorDebugVariableHomeEnumVtbl
+    {
+        BEGIN_INTERFACE
+        
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
+            ICorDebugVariableHomeEnum * This,
+            /* [in] */ REFIID riid,
+            /* [annotation][iid_is][out] */ 
+            _COM_Outptr_  void **ppvObject);
+        
+        ULONG ( STDMETHODCALLTYPE *AddRef )( 
+            ICorDebugVariableHomeEnum * This);
+        
+        ULONG ( STDMETHODCALLTYPE *Release )( 
+            ICorDebugVariableHomeEnum * This);
+        
+        HRESULT ( STDMETHODCALLTYPE *Skip )( 
+            ICorDebugVariableHomeEnum * This,
+            /* [in] */ ULONG celt);
+        
+        HRESULT ( STDMETHODCALLTYPE *Reset )( 
+            ICorDebugVariableHomeEnum * This);
+        
+        HRESULT ( STDMETHODCALLTYPE *Clone )( 
+            ICorDebugVariableHomeEnum * This,
+            /* [out] */ ICorDebugEnum **ppEnum);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetCount )( 
+            ICorDebugVariableHomeEnum * This,
+            /* [out] */ ULONG *pcelt);
+        
+        HRESULT ( STDMETHODCALLTYPE *Next )( 
+            ICorDebugVariableHomeEnum * This,
+            /* [in] */ ULONG celt,
+            /* [length_is][size_is][out] */ ICorDebugVariableHome *homes[  ],
+            /* [out] */ ULONG *pceltFetched);
+        
+        END_INTERFACE
+    } ICorDebugVariableHomeEnumVtbl;
+
+    interface ICorDebugVariableHomeEnum
+    {
+        CONST_VTBL struct ICorDebugVariableHomeEnumVtbl *lpVtbl;
+    };
+
+    
+
+#ifdef COBJMACROS
+
+
+#define ICorDebugVariableHomeEnum_QueryInterface(This,riid,ppvObject)  \
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 
+
+#define ICorDebugVariableHomeEnum_AddRef(This) \
+    ( (This)->lpVtbl -> AddRef(This) ) 
+
+#define ICorDebugVariableHomeEnum_Release(This)        \
+    ( (This)->lpVtbl -> Release(This) ) 
+
+
+#define ICorDebugVariableHomeEnum_Skip(This,celt)      \
+    ( (This)->lpVtbl -> Skip(This,celt) ) 
+
+#define ICorDebugVariableHomeEnum_Reset(This)  \
+    ( (This)->lpVtbl -> Reset(This) ) 
+
+#define ICorDebugVariableHomeEnum_Clone(This,ppEnum)   \
+    ( (This)->lpVtbl -> Clone(This,ppEnum) ) 
+
+#define ICorDebugVariableHomeEnum_GetCount(This,pcelt) \
+    ( (This)->lpVtbl -> GetCount(This,pcelt) ) 
+
+
+#define ICorDebugVariableHomeEnum_Next(This,celt,homes,pceltFetched)   \
+    ( (This)->lpVtbl -> Next(This,celt,homes,pceltFetched) ) 
+
+#endif /* COBJMACROS */
+
+
+#endif         /* C style interface */
+
+
+
+
+#endif         /* __ICorDebugVariableHomeEnum_INTERFACE_DEFINED__ */
+
+
 #ifndef __ICorDebugCodeEnum_INTERFACE_DEFINED__
 #define __ICorDebugCodeEnum_INTERFACE_DEFINED__
 
@@ -16522,6 +16893,86 @@ EXTERN_C const IID IID_ICorDebugType;
 #endif         /* __ICorDebugType_INTERFACE_DEFINED__ */
 
 
+#ifndef __ICorDebugType2_INTERFACE_DEFINED__
+#define __ICorDebugType2_INTERFACE_DEFINED__
+
+/* interface ICorDebugType2 */
+/* [unique][uuid][local][object] */ 
+
+
+EXTERN_C const IID IID_ICorDebugType2;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+    
+    MIDL_INTERFACE("e6e91d79-693d-48bc-b417-8284b4f10fb5")
+    ICorDebugType2 : public IUnknown
+    {
+    public:
+        virtual HRESULT STDMETHODCALLTYPE GetTypeID( 
+            /* [out] */ COR_TYPEID *id) = 0;
+        
+    };
+    
+    
+#else  /* C style interface */
+
+    typedef struct ICorDebugType2Vtbl
+    {
+        BEGIN_INTERFACE
+        
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
+            ICorDebugType2 * This,
+            /* [in] */ REFIID riid,
+            /* [annotation][iid_is][out] */ 
+            _COM_Outptr_  void **ppvObject);
+        
+        ULONG ( STDMETHODCALLTYPE *AddRef )( 
+            ICorDebugType2 * This);
+        
+        ULONG ( STDMETHODCALLTYPE *Release )( 
+            ICorDebugType2 * This);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetTypeID )( 
+            ICorDebugType2 * This,
+            /* [out] */ COR_TYPEID *id);
+        
+        END_INTERFACE
+    } ICorDebugType2Vtbl;
+
+    interface ICorDebugType2
+    {
+        CONST_VTBL struct ICorDebugType2Vtbl *lpVtbl;
+    };
+
+    
+
+#ifdef COBJMACROS
+
+
+#define ICorDebugType2_QueryInterface(This,riid,ppvObject)     \
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 
+
+#define ICorDebugType2_AddRef(This)    \
+    ( (This)->lpVtbl -> AddRef(This) ) 
+
+#define ICorDebugType2_Release(This)   \
+    ( (This)->lpVtbl -> Release(This) ) 
+
+
+#define ICorDebugType2_GetTypeID(This,id)      \
+    ( (This)->lpVtbl -> GetTypeID(This,id) ) 
+
+#endif /* COBJMACROS */
+
+
+#endif         /* C style interface */
+
+
+
+
+#endif         /* __ICorDebugType2_INTERFACE_DEFINED__ */
+
+
 #ifndef __ICorDebugErrorInfoEnum_INTERFACE_DEFINED__
 #define __ICorDebugErrorInfoEnum_INTERFACE_DEFINED__
 
@@ -16970,15 +17421,15 @@ EXTERN_C const IID IID_ICorDebugBlockingObjectEnum;
 #endif         /* __ICorDebugBlockingObjectEnum_INTERFACE_DEFINED__ */
 
 
-/* interface __MIDL_itf_cordebug_0000_0117 */
+/* interface __MIDL_itf_cordebug_0000_0121 */
 /* [local] */ 
 
 #pragma warning(push)
 #pragma warning(disable:28718)
 
 
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0117_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0117_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0121_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0121_v0_0_s_ifspec;
 
 #ifndef __ICorDebugMDA_INTERFACE_DEFINED__
 #define __ICorDebugMDA_INTERFACE_DEFINED__
@@ -17118,7 +17569,7 @@ EXTERN_C const IID IID_ICorDebugMDA;
 #endif         /* __ICorDebugMDA_INTERFACE_DEFINED__ */
 
 
-/* interface __MIDL_itf_cordebug_0000_0118 */
+/* interface __MIDL_itf_cordebug_0000_0122 */
 /* [local] */ 
 
 #pragma warning(pop)
@@ -17126,8 +17577,8 @@ EXTERN_C const IID IID_ICorDebugMDA;
 #pragma warning(disable:28718) 
 
 
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0118_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0118_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0122_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0122_v0_0_s_ifspec;
 
 #ifndef __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__
 #define __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__
@@ -17243,14 +17694,14 @@ EXTERN_C const IID IID_ICorDebugEditAndContinueErrorInfo;
 #endif         /* __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__ */
 
 
-/* interface __MIDL_itf_cordebug_0000_0119 */
+/* interface __MIDL_itf_cordebug_0000_0123 */
 /* [local] */ 
 
 #pragma warning(pop)
 
 
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0119_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0119_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0123_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0123_v0_0_s_ifspec;
 
 #ifndef __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__
 #define __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__