Add support for the new ISOSDacInterface14 (#4545)
authorDavid Wrighton <davidwr@microsoft.com>
Fri, 29 Mar 2024 14:01:42 +0000 (07:01 -0700)
committerGitHub <noreply@github.com>
Fri, 29 Mar 2024 14:01:42 +0000 (07:01 -0700)
- Adds support for SOS not needing the DomainLocalModule and ThreadLocalModule apis to access static fields.
- Adds support for viewing static fields on generic types.
 - note... This only works if you can either get an object that is the exact static type to use DumpObject, or a non generic shared shared EEClass and use DumpClass, as there is no print statics for the DumpMethodTable SOS command

src/SOS/Strike/exts.h
src/SOS/Strike/util.cpp
src/shared/inc/sospriv.idl
src/shared/pal/prebuilt/idl/sospriv_i.cpp
src/shared/pal/prebuilt/inc/sospriv.h

index 35a1959d9614005a07e0c06e819c0ffb26302581..4b1212b34cea2d9a0cf8b5923f4b36a3d376d615 100644 (file)
@@ -579,6 +579,12 @@ extern ReadVirtualCache *rvCache;
     if (FAILED(ret)) return;                          \
 }
 
+#define move_xp_retHRESULT(dst, src)                  \
+{                                                     \
+    HRESULT ret = MOVE(dst, src);                     \
+    if (FAILED(ret)) return ret;                      \
+}
+
 #define moveBlock(dst, src, size)                     \
 {                                                     \
     HRESULT ret = MOVEBLOCK(dst, src, size);          \
index 4d4e0d8c33c71a7fb8f0360e4a5134ff2a06cbb7..786c52647f09c03404b05ae6b117cf03b0fa962a 100644 (file)
@@ -576,42 +576,77 @@ void DisplayDataMember (DacpFieldDescData* pFD, DWORD_PTR dwAddr, BOOL fAlign=TR
     }
 }
 
-void GetStaticFieldPTR(DWORD_PTR* pOutPtr, DacpDomainLocalModuleData* pDLMD, DacpMethodTableData* pMTD, DacpFieldDescData* pFDD, BYTE* pFlags = 0)
+HRESULT GetStaticFieldPTR(DWORD_PTR* pOutPtr, DacpDomainLocalModuleData* pDLMD, ISOSDacInterface14* pSOS14, CLRDATA_ADDRESS cdaMT, DacpMethodTableData* pMTD, DacpFieldDescData* pFDD, BYTE* pFlags = 0)
 {
     DWORD_PTR dwTmp;
+    CLRDATA_ADDRESS pBaseAddress = 0;
 
-    if (pFDD->Type == ELEMENT_TYPE_VALUETYPE
-            || pFDD->Type == ELEMENT_TYPE_CLASS)
+    BOOL isGCStatic = pFDD->Type == ELEMENT_TYPE_VALUETYPE || pFDD->Type == ELEMENT_TYPE_CLASS;
+
+    if (pSOS14)
     {
-        dwTmp = (DWORD_PTR) pDLMD->pGCStaticDataStart + pFDD->dwOffset;
+        HRESULT hr = pSOS14->GetStaticBaseAddress(cdaMT, !isGCStatic ? &pBaseAddress : NULL, isGCStatic ? &pBaseAddress : NULL);
+        if (FAILED(hr))
+        {
+            ExtOut("GetStaticBaseAddress failed");
+            return hr;
+        }
     }
     else
     {
-        dwTmp = (DWORD_PTR) pDLMD->pNonGCStaticDataStart + pFDD->dwOffset;
+        if (isGCStatic)
+        {
+            pBaseAddress = pDLMD->pGCStaticDataStart;
+        }
+        else
+        {
+            pBaseAddress = pDLMD->pNonGCStaticDataStart;
+        }
     }
 
+    dwTmp = (DWORD_PTR)pBaseAddress + pFDD->dwOffset;
+
     *pOutPtr = 0;
 
-    if (pMTD->bIsDynamic)
+    if (pSOS14)
     {
-        ExtOut("dynamic statics NYI");
-        return;
+        MethodTableInitializationFlags initFlags;
+        if (pFlags)
+            *pFlags = 0;
+        HRESULT hr = pSOS14->GetMethodTableInitializationFlags(cdaMT, &initFlags);
+        if (FAILED(hr))
+        {
+            ExtOut("GetMethodTableInitializationFlags failed");
+        }
+        else
+        {
+            if (pFlags)
+                *pFlags = (BYTE)initFlags; // It so happens that these two types of flags match up
+        }
+        *pOutPtr = dwTmp;
     }
     else
     {
-        if (pFlags && pMTD->bIsShared)
+        if (pMTD->bIsDynamic)
         {
-            BYTE flags;
-            DWORD_PTR pTargetFlags = (DWORD_PTR) pDLMD->pClassData + RidFromToken(pMTD->cl) - 1;
-            move_xp (flags, pTargetFlags);
-
-            *pFlags = flags;
+            ExtOut("dynamic statics NYI");
+            return E_FAIL;
         }
+        else
+        {
+            if (pFlags && pMTD->bIsShared)
+            {
+                BYTE flags;
+                DWORD_PTR pTargetFlags = (DWORD_PTR) pDLMD->pClassData + RidFromToken(pMTD->cl) - 1;
+                move_xp_retHRESULT (flags, pTargetFlags);
 
+                *pFlags = flags;
+            }
 
-        *pOutPtr = dwTmp;
+            *pOutPtr = dwTmp;
+        }
     }
-    return;
+    return S_OK;
 }
 
 void GetDLMFlags(DacpDomainLocalModuleData* pDLMD, DacpMethodTableData* pMTD, BYTE* pFlags)
@@ -635,44 +670,84 @@ void GetDLMFlags(DacpDomainLocalModuleData* pDLMD, DacpMethodTableData* pMTD, BY
     return;
 }
 
-void GetThreadStaticFieldPTR(DWORD_PTR* pOutPtr, DacpThreadLocalModuleData* pTLMD, DacpMethodTableData* pMTD, DacpFieldDescData* pFDD, BYTE* pFlags = 0)
+HRESULT GetThreadStaticFieldPTR(DWORD_PTR* pOutPtr, CLRDATA_ADDRESS cdaThread, DacpThreadLocalModuleData* pTLMD, ISOSDacInterface14* pSOS14, CLRDATA_ADDRESS cdaMT, DacpMethodTableData* pMTD, DacpFieldDescData* pFDD, BYTE* pFlags = 0)
 {
     DWORD_PTR dwTmp;
+    CLRDATA_ADDRESS pBase = 0;
+    BOOL isGCStatic = pFDD->Type == ELEMENT_TYPE_VALUETYPE || pFDD->Type == ELEMENT_TYPE_CLASS;
+    if (pFlags)
+        *pFlags = 0;
 
-    if (pFDD->Type == ELEMENT_TYPE_VALUETYPE
-            || pFDD->Type == ELEMENT_TYPE_CLASS)
+    if (pSOS14)
     {
-        dwTmp = (DWORD_PTR) pTLMD->pGCStaticDataStart + pFDD->dwOffset;
+        HRESULT hr = pSOS14->GetThreadStaticBaseAddress(cdaMT, cdaThread, !isGCStatic ? &pBase : NULL, isGCStatic ? &pBase : NULL);
+        if (FAILED(hr))
+        {
+            ExtOut("GetThreadStaticBaseAddress failed");
+            return hr;
+        }
+
+        if (pBase != 0)
+        {
+            if (pFlags)
+                *pFlags = 4; // Flag 4 indicates that the thread static data is allocated
+        }
     }
     else
     {
-        dwTmp = (DWORD_PTR) pTLMD->pNonGCStaticDataStart + pFDD->dwOffset;
+        if (isGCStatic)
+        {
+            pBase = pTLMD->pGCStaticDataStart;
+        }
+        else
+        {
+            pBase = pTLMD->pNonGCStaticDataStart;
+        }
     }
 
+    dwTmp = (DWORD_PTR)pBase + pFDD->dwOffset;
+
     *pOutPtr = 0;
 
-    if (pMTD->bIsDynamic)
+    if (pSOS14)
     {
-        ExtOut("dynamic thread statics NYI");
-        return;
+        MethodTableInitializationFlags initFlags;
+        HRESULT hr = pSOS14->GetMethodTableInitializationFlags(cdaMT, &initFlags);
+        if (FAILED(hr))
+        {
+            ExtOut("GetMethodTableInitializationFlags failed");
+        }
+        else
+        {
+            *pFlags |= (BYTE)initFlags; // It so happens that these two types of flags match up
+        }
+        *pOutPtr = dwTmp;
     }
     else
     {
-        if (pFlags)
+        if (pMTD->bIsDynamic)
         {
-            BYTE flags;
-            DWORD_PTR pTargetFlags = (DWORD_PTR) pTLMD->pClassData + RidFromToken(pMTD->cl) - 1;
-            move_xp (flags, pTargetFlags);
-
-            *pFlags = flags;
+            ExtOut("dynamic thread statics NYI");
+            return E_FAIL;
         }
+        else
+        {
+            if (pFlags)
+            {
+                BYTE flags;
+                DWORD_PTR pTargetFlags = (DWORD_PTR) pTLMD->pClassData + RidFromToken(pMTD->cl) - 1;
+                move_xp_retHRESULT (flags, pTargetFlags);
 
-        *pOutPtr = dwTmp;
+                *pFlags = flags;
+            }
+
+            *pOutPtr = dwTmp;
+        }
     }
-    return;
+    return S_OK;
 }
 
-void DisplaySharedStatic(ULONG64 dwModuleDomainID, DacpMethodTableData* pMT, DacpFieldDescData *pFD)
+void DisplaySharedStatic(ULONG64 dwModuleDomainID, CLRDATA_ADDRESS cdaMT, DacpMethodTableData* pMT, DacpFieldDescData *pFD)
 {
     DacpAppDomainStoreData adsData;
     if (adsData.Request(g_sos)!=S_OK)
@@ -721,7 +796,7 @@ void DisplaySharedStatic(ULONG64 dwModuleDomainID, DacpMethodTableData* pMT, Dac
 
         DWORD_PTR dwTmp;
         BYTE Flags = 0;
-        GetStaticFieldPTR(&dwTmp, &vDomainLocalModule , pMT, pFD, &Flags);
+        GetStaticFieldPTR(&dwTmp, &vDomainLocalModule, NULL, cdaMT, pMT, pFD, &Flags);
 
         if ((Flags&1) == 0) {
             // We have not initialized this yet.
@@ -740,7 +815,7 @@ void DisplaySharedStatic(ULONG64 dwModuleDomainID, DacpMethodTableData* pMT, Dac
     ExtOut(" <<\n");
 }
 
-void DisplayThreadStatic (DacpModuleData* pModule, DacpMethodTableData* pMT, DacpFieldDescData *pFD, BOOL fIsShared)
+void DisplayThreadStatic (DacpModuleData* pModule, CLRDATA_ADDRESS cdaMT, DacpMethodTableData* pMT, DacpFieldDescData *pFD, BOOL fIsShared)
 {
     SIZE_T dwModuleIndex = (SIZE_T)pModule->dwModuleIndex;
     SIZE_T dwModuleDomainID = (SIZE_T)pModule->dwModuleID;
@@ -763,69 +838,86 @@ void DisplayThreadStatic (DacpModuleData* pModule, DacpMethodTableData* pMT, Dac
         {
             CLRDATA_ADDRESS appDomainAddr = vThread.domain;
 
-            // Get the DLM (we need this to check the ClassInit flags).
-            // It's annoying that we have to issue one request for
-            // domain-neutral modules and domain-specific modules.
-            DacpDomainLocalModuleData vDomainLocalModule;
-            if (fIsShared)
+            ISOSDacInterface14 *pSOS14 = nullptr;
+            HRESULT hr = g_sos->QueryInterface(__uuidof(ISOSDacInterface14), reinterpret_cast<LPVOID*>(&pSOS14));
+            if (SUCCEEDED(hr))
             {
-                if (g_sos->GetDomainLocalModuleDataFromAppDomain(appDomainAddr, (int)dwModuleDomainID, &vDomainLocalModule) != S_OK)
+                DWORD_PTR dwTmp;
+                BYTE Flags = 0;
+                HRESULT hr = GetThreadStaticFieldPTR(&dwTmp, CurThread, NULL, pSOS14, cdaMT, pMT, pFD, &Flags);
+                pSOS14->Release();
+                if (SUCCEEDED(hr) && (Flags&4))
                 {
-                    // On .NET Core, dwModuleDomainID is the address of the DomainLocalModule.
-                    if (vDomainLocalModule.Request(g_sos, dwModuleDomainID) != S_OK)
+                    ExtOut(" %x:", vThread.osThreadId);
+                    DisplayDataMember(pFD, dwTmp, FALSE);
+                }
+            }
+            else
+            {
+                // Get the DLM (we need this to check the ClassInit flags).
+                // It's annoying that we have to issue one request for
+                // domain-neutral modules and domain-specific modules.
+                DacpDomainLocalModuleData vDomainLocalModule;
+                if (fIsShared)
+                {
+                    if (g_sos->GetDomainLocalModuleDataFromAppDomain(appDomainAddr, (int)dwModuleDomainID, &vDomainLocalModule) != S_OK)
                     {
-                        // Not initialized, go to next thread and continue looping
+                        // On .NET Core, dwModuleDomainID is the address of the DomainLocalModule.
+                        if (vDomainLocalModule.Request(g_sos, dwModuleDomainID) != S_OK)
+                        {
+                            // Not initialized, go to next thread and continue looping
+                            CurThread = vThread.nextThread;
+                            continue;
+                        }
+                    }
+                }
+                else
+                {
+                    if (g_sos->GetDomainLocalModuleDataFromModule(pMT->Module, &vDomainLocalModule) != S_OK)
+                    {
+                        // Not initialized, go to next thread
+                        // and continue looping
                         CurThread = vThread.nextThread;
                         continue;
                     }
                 }
-            }
-            else
-            {
-                if (g_sos->GetDomainLocalModuleDataFromModule(pMT->Module, &vDomainLocalModule) != S_OK)
+
+                // Get the TLM
+                DacpThreadLocalModuleData vThreadLocalModule;
+                if (g_sos->GetThreadLocalModuleData(CurThread, (int)dwModuleIndex, &vThreadLocalModule) != S_OK)
                 {
                     // Not initialized, go to next thread
                     // and continue looping
                     CurThread = vThread.nextThread;
                     continue;
                 }
-            }
 
-            // Get the TLM
-            DacpThreadLocalModuleData vThreadLocalModule;
-            if (g_sos->GetThreadLocalModuleData(CurThread, (int)dwModuleIndex, &vThreadLocalModule) != S_OK)
-            {
-                // Not initialized, go to next thread
-                // and continue looping
-                CurThread = vThread.nextThread;
-                continue;
-            }
+                DWORD_PTR dwTmp;
+                BYTE Flags = 0;
+                GetThreadStaticFieldPTR(&dwTmp, CurThread, &vThreadLocalModule, NULL, cdaMT, pMT, pFD, &Flags);
 
-            DWORD_PTR dwTmp;
-            BYTE Flags = 0;
-            GetThreadStaticFieldPTR(&dwTmp, &vThreadLocalModule, pMT, pFD, &Flags);
+                if ((Flags&4) == 0)
+                {
+                    // Not allocated, go to next thread
+                    // and continue looping
+                    CurThread = vThread.nextThread;
+                    continue;
+                }
 
-            if ((Flags&4) == 0)
-            {
-                // Not allocated, go to next thread
-                // and continue looping
-                CurThread = vThread.nextThread;
-                continue;
-            }
+                Flags = 0;
+                GetDLMFlags(&vDomainLocalModule, pMT, &Flags);
 
-            Flags = 0;
-            GetDLMFlags(&vDomainLocalModule, pMT, &Flags);
+                if ((Flags&1) == 0)
+                {
+                    // Not initialized, go to next thread
+                    // and continue looping
+                    CurThread = vThread.nextThread;
+                    continue;
+                }
 
-            if ((Flags&1) == 0)
-            {
-                // Not initialized, go to next thread
-                // and continue looping
-                CurThread = vThread.nextThread;
-                continue;
+                ExtOut(" %x:", vThread.osThreadId);
+                DisplayDataMember(pFD, dwTmp, FALSE);
             }
-
-            ExtOut(" %x:", vThread.osThreadId);
-            DisplayDataMember(pFD, dwTmp, FALSE);
         }
 
         // Go to next thread
@@ -1045,7 +1137,7 @@ void DisplayFields(CLRDATA_ADDRESS cdaMT, DacpMethodTableData *pMTD, DacpMethodT
                     DacpModuleData vModule;
                     if (vModule.Request(g_sos,pMTD->Module) == S_OK)
                     {
-                        DisplayThreadStatic(&vModule, pMTD, &vFieldDesc, fIsShared);
+                        DisplayThreadStatic(&vModule, cdaMT, pMTD, &vFieldDesc, fIsShared);
                     }
                 }
                 else if (vFieldDesc.bIsContextLocal)
@@ -1075,7 +1167,7 @@ void DisplayFields(CLRDATA_ADDRESS cdaMT, DacpMethodTableData *pMTD, DacpMethodT
                     DacpModuleData vModule;
                     if (vModule.Request(g_sos,pMTD->Module) == S_OK)
                     {
-                        DisplaySharedStatic(vModule.dwModuleID, pMTD, &vFieldDesc);
+                        DisplaySharedStatic(vModule.dwModuleID, cdaMT, pMTD, &vFieldDesc);
                     }
                 }
             }
@@ -1084,22 +1176,34 @@ void DisplayFields(CLRDATA_ADDRESS cdaMT, DacpMethodTableData *pMTD, DacpMethodT
                 ExtOut("%8s ", "static");
 
                 DacpDomainLocalModuleData vDomainLocalModule;
-
-                // The MethodTable isn't shared, so the module must not be loaded domain neutral.  We can
-                // get the specific DomainLocalModule instance without needing to know the AppDomain in advance.
-                if (g_sos->GetDomainLocalModuleDataFromModule(pMTD->Module, &vDomainLocalModule) != S_OK)
+                DWORD_PTR dwTmp = 0;
+                bool calledGetStaticFieldPTR = false;
+
+                // If there is support for ISOSDacInterface14 there may be no DomainLocalModule, so attempt to get the statics from ISOSDacInterface14,
+                // which was added to support statics access when DomainLocalModules were removed from the product
+                    ISOSDacInterface14 *pSOS14 = nullptr;
+                    HRESULT hr = g_sos->QueryInterface(__uuidof(ISOSDacInterface14), reinterpret_cast<LPVOID*>(&pSOS14));
+                    if (SUCCEEDED(hr))
+                    {
+                        calledGetStaticFieldPTR = SUCCEEDED(GetStaticFieldPTR(&dwTmp, NULL, pSOS14, cdaMT, pMTD, &vFieldDesc));
+                        pSOS14->Release();
+                    }
+                else if (SUCCEEDED(g_sos->GetDomainLocalModuleDataFromModule(pMTD->Module, &vDomainLocalModule)))
                 {
-                    ExtOut(" <no information>\n");
+                    calledGetStaticFieldPTR = SUCCEEDED(GetStaticFieldPTR(&dwTmp, &vDomainLocalModule, NULL, cdaMT, pMTD, &vFieldDesc));
                 }
-                else
+
+                if (calledGetStaticFieldPTR)
                 {
-                    DWORD_PTR dwTmp;
-                    GetStaticFieldPTR(&dwTmp, &vDomainLocalModule, pMTD, &vFieldDesc);
                     DisplayDataMember(&vFieldDesc, dwTmp);
 
                     NameForToken_s(TokenFromRid(vFieldDesc.mb, mdtFieldDef), pImport, g_mdName, mdNameLen, false);
                     ExtOut(" %S\n", g_mdName);
                 }
+                else
+                {
+                    ExtOut(" <no information>\n");
+                }
             }
         }
         else
index a0a42fff8910faef29f1094d8ce1897c0698394e..c377df57a15307d883022e19b31cd578c4138284 100644 (file)
@@ -43,12 +43,15 @@ typedef unsigned int size_t;
 typedef int ModuleMapType;
 typedef int VCSHeapType;
 typedef int LoaderHeapKind;
+typedef int MethodTableInitializationFlags;
 cpp_quote("#endif")
 
 
 cpp_quote("typedef enum { TYPEDEFTOMETHODTABLE, TYPEREFTOMETHODTABLE } ModuleMapType;")
 cpp_quote("typedef enum {IndcellHeap, LookupHeap, ResolveHeap, DispatchHeap, CacheEntryHeap, VtableHeap} VCSHeapType;")
 cpp_quote("typedef enum {LoaderHeapKindNormal = 0, LoaderHeapKindExplicitControl = 1} LoaderHeapKind;")
+cpp_quote("typedef enum {MethodTableInitialized = 1, MethodTableInitializationFailed = 2} MethodTableInitializationFlags;")
+cpp_quote("typedef enum {FreeUnknownRegion = 0, FreeGlobalHugeRegion = 1, FreeGlobalRegion = 2, FreeRegion = 3, FreeSohSegment = 4, FreeUohSegment = 5 } FreeRegionKind;")
 
 typedef void (*MODULEMAPTRAVERSE)(UINT index, CLRDATA_ADDRESS methodTable,LPVOID token);
 typedef void (*VISITHEAP)(CLRDATA_ADDRESS blockData,size_t blockSize,BOOL blockIsCurrentBlock);
@@ -172,6 +175,32 @@ interface ISOSStackRefEnum  : ISOSEnum
 }
 
 
+cpp_quote("#ifndef _SOS_MemoryRegion_")
+cpp_quote("#define _SOS_MemoryRegion_")
+
+typedef struct _SOSMemoryRegion
+{
+    CLRDATA_ADDRESS Start;
+    CLRDATA_ADDRESS Size;
+    CLRDATA_ADDRESS ExtraData;
+    int Heap;
+} SOSMemoryRegion;
+
+cpp_quote("#endif // _SOS_MemoryRegion_")
+
+[
+    object,
+    local,
+    uuid(E4B860EC-337A-40C0-A591-F09A9680690F)
+]
+interface ISOSMemoryEnum : ISOSEnum
+{
+    HRESULT Next([in] unsigned int count,
+                 [out, size_is(count), length_is(*pNeeded)] SOSMemoryRegion memRegion[],
+                 [out] unsigned int *pNeeded);
+}
+
+
 [
     object,
     local,
@@ -465,7 +494,7 @@ interface ISOSDacInterface12 : IUnknown
 [
     object,
     local,
-    uuid(3176a8ed-597b-4f54-a71f-83695c6a8c5d)
+    uuid(3176a8ed-597b-4f54-a71f-83695c6a8c5e)
 ]
 interface ISOSDacInterface13 : IUnknown
 {
@@ -473,4 +502,20 @@ interface ISOSDacInterface13 : IUnknown
     HRESULT GetDomainLoaderAllocator(CLRDATA_ADDRESS domainAddress, CLRDATA_ADDRESS *pLoaderAllocator);
     HRESULT GetLoaderAllocatorHeapNames(int count, const char **ppNames, int *pNeeded);
     HRESULT GetLoaderAllocatorHeaps(CLRDATA_ADDRESS loaderAllocator, int count, CLRDATA_ADDRESS *pLoaderHeaps, LoaderHeapKind *pKinds, int *pNeeded);
+    HRESULT GetHandleTableMemoryRegions(ISOSMemoryEnum **ppEnum);
+    HRESULT GetGCBookkeepingMemoryRegions(ISOSMemoryEnum **ppEnum);
+    HRESULT GetGCFreeRegions(ISOSMemoryEnum **ppEnum);
+    HRESULT LockedFlush();
+}
+
+[
+    object,
+    local,
+    uuid(9aa22aca-6dc6-4a0c-b4e0-70d2416b9837)
+]
+interface ISOSDacInterface14 : IUnknown
+{
+    HRESULT GetStaticBaseAddress(CLRDATA_ADDRESS methodTable, CLRDATA_ADDRESS *nonGCStaticsAddress, CLRDATA_ADDRESS *GCStaticsAddress);
+    HRESULT GetThreadStaticBaseAddress(CLRDATA_ADDRESS methodTable, CLRDATA_ADDRESS thread, CLRDATA_ADDRESS *nonGCStaticsAddress, CLRDATA_ADDRESS *GCStaticsAddress);
+    HRESULT GetMethodTableInitializationFlags(CLRDATA_ADDRESS methodTable, MethodTableInitializationFlags *initializationStatus);
 }
index 07f02d061e86c450bb2d7f56dd91746cf94fe8c9..f070ae5816a8a8ca8fcd02011568cc773e720a31 100644 (file)
@@ -5,9 +5,9 @@
 /* link this file in with the server and any clients */
 
 
- /* File created by MIDL compiler version 8.01.0626 */
+ /* File created by MIDL compiler version 8.01.0628 */
 /* Compiler settings for sospriv.idl:
-    Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0626 
+    Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0628 
     protocol : dce , ms_ext, c_ext, robust
     error checks: allocation ref bounds_check enum stub_data 
     VC __declspec() decoration level: 
@@ -77,6 +77,9 @@ MIDL_DEFINE_GUID(IID, IID_ISOSStackRefErrorEnum,0x774F4E1B,0xFB7B,0x491B,0x97,0x
 MIDL_DEFINE_GUID(IID, IID_ISOSStackRefEnum,0x8FA642BD,0x9F10,0x4799,0x9A,0xA3,0x51,0x2A,0xE7,0x8C,0x77,0xEE);
 
 
+MIDL_DEFINE_GUID(IID, IID_ISOSMemoryEnum,0xE4B860EC,0x337A,0x40C0,0xA5,0x91,0xF0,0x9A,0x96,0x80,0x69,0x0F);
+
+
 MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface,0x436f00f2,0xb42a,0x4b9f,0x87,0x0c,0xe7,0x3d,0xb6,0x6a,0xe9,0x30);
 
 
@@ -113,7 +116,10 @@ MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface11,0x96BA1DB9,0x14CD,0x4492,0x80,0x65,
 MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface12,0x1b93bacc,0x8ca4,0x432d,0x94,0x3a,0x3e,0x6e,0x7e,0xc0,0xb0,0xa3);
 
 
-MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface13,0x3176a8ed,0x597b,0x4f54,0xa7,0x1f,0x83,0x69,0x5c,0x6a,0x8c,0x5d);
+MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface13,0x3176a8ed,0x597b,0x4f54,0xa7,0x1f,0x83,0x69,0x5c,0x6a,0x8c,0x5e);
+
+
+MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface14,0x9aa22aca,0x6dc6,0x4a0c,0xb4,0xe0,0x70,0xd2,0x41,0x6b,0x98,0x37);
 
 #undef MIDL_DEFINE_GUID
 
index c5dd1d488e65503c31ad7de74ba64e6a0c6bba9d..855696ef0ce4ef45acca7fe91ab5ad111389b6c4 100644 (file)
@@ -73,6 +73,13 @@ typedef interface ISOSStackRefEnum ISOSStackRefEnum;
 #endif  /* __ISOSStackRefEnum_FWD_DEFINED__ */
 
 
+#ifndef __ISOSMemoryEnum_FWD_DEFINED__
+#define __ISOSMemoryEnum_FWD_DEFINED__
+typedef interface ISOSMemoryEnum ISOSMemoryEnum;
+
+#endif         /* __ISOSMemoryEnum_FWD_DEFINED__ */
+
+
 #ifndef __ISOSDacInterface_FWD_DEFINED__
 #define __ISOSDacInterface_FWD_DEFINED__
 typedef interface ISOSDacInterface ISOSDacInterface;
@@ -198,6 +205,8 @@ typedef int VCSHeapType;
 typedef enum { TYPEDEFTOMETHODTABLE, TYPEREFTOMETHODTABLE } ModuleMapType;
 typedef enum {IndcellHeap, LookupHeap, ResolveHeap, DispatchHeap, CacheEntryHeap, VtableHeap} VCSHeapType;
 typedef enum {LoaderHeapKindNormal = 0, LoaderHeapKindExplicitControl = 1} LoaderHeapKind;
+typedef enum {MethodTableInitialized = 1, MethodTableInitializationFailed = 2} MethodTableInitializationFlags;
+typedef enum {FreeUnknownRegion = 0, FreeGlobalHugeRegion = 1, FreeGlobalRegion = 2, FreeRegion = 3, FreeSohSegment = 4, FreeUohSegment = 5 } FreeRegionKind;
 typedef void ( *MODULEMAPTRAVERSE )(
     UINT index,
     CLRDATA_ADDRESS methodTable,
@@ -489,6 +498,17 @@ typedef struct _SOS_StackRefError
 extern RPC_IF_HANDLE __MIDL_itf_sospriv_0000_0002_v0_0_c_ifspec;
 extern RPC_IF_HANDLE __MIDL_itf_sospriv_0000_0002_v0_0_s_ifspec;
 
+#ifndef _SOS_MemoryRegion_
+#define _SOS_MemoryRegion_
+typedef struct _SOSMemoryRegion
+    {
+    CLRDATA_ADDRESS Start;
+    CLRDATA_ADDRESS Size;
+    CLRDATA_ADDRESS ExtraData;
+    int Heap;
+    }  SOSMemoryRegion;
+#endif // _SOS_MemoryRegion_
+
 #ifndef __ISOSStackRefErrorEnum_INTERFACE_DEFINED__
 #define __ISOSStackRefErrorEnum_INTERFACE_DEFINED__
 
@@ -594,6 +614,112 @@ EXTERN_C const IID IID_ISOSStackRefErrorEnum;
 #endif  /* __ISOSStackRefErrorEnum_INTERFACE_DEFINED__ */
 
 
+
+#ifndef __ISOSMemoryEnum_INTERFACE_DEFINED__
+#define __ISOSMemoryEnum_INTERFACE_DEFINED__
+
+/* interface ISOSMemoryEnum */
+/* [uuid][local][object] */
+
+
+EXTERN_C const IID IID_ISOSMemoryEnum;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+    MIDL_INTERFACE("E4B860EC-337A-40C0-A591-F09A9680690F")
+    ISOSMemoryEnum : public ISOSEnum
+    {
+    public:
+        virtual HRESULT STDMETHODCALLTYPE Next(
+            /* [in] */ unsigned int count,
+            /* [length_is][size_is][out] */ SOSMemoryRegion memRegion[  ],
+            /* [out] */ unsigned int *pNeeded) = 0;
+
+    };
+
+
+#else  /* C style interface */
+
+    typedef struct ISOSMemoryEnumVtbl
+    {
+        BEGIN_INTERFACE
+
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+            ISOSMemoryEnum * This,
+            /* [in] */ REFIID riid,
+            /* [annotation][iid_is][out] */
+            _COM_Outptr_  void **ppvObject);
+
+        ULONG ( STDMETHODCALLTYPE *AddRef )(
+            ISOSMemoryEnum * This);
+
+        ULONG ( STDMETHODCALLTYPE *Release )(
+            ISOSMemoryEnum * This);
+
+        HRESULT ( STDMETHODCALLTYPE *Skip )(
+            ISOSMemoryEnum * This,
+            /* [in] */ unsigned int count);
+
+        HRESULT ( STDMETHODCALLTYPE *Reset )(
+            ISOSMemoryEnum * This);
+
+        HRESULT ( STDMETHODCALLTYPE *GetCount )(
+            ISOSMemoryEnum * This,
+            /* [out] */ unsigned int *pCount);
+
+        HRESULT ( STDMETHODCALLTYPE *Next )(
+            ISOSMemoryEnum * This,
+            /* [in] */ unsigned int count,
+            /* [length_is][size_is][out] */ SOSMemoryRegion memRegion[  ],
+            /* [out] */ unsigned int *pNeeded);
+
+        END_INTERFACE
+    } ISOSMemoryEnumVtbl;
+
+    interface ISOSMemoryEnum
+    {
+        CONST_VTBL struct ISOSMemoryEnumVtbl *lpVtbl;
+    };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ISOSMemoryEnum_QueryInterface(This,riid,ppvObject)     \
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ISOSMemoryEnum_AddRef(This)    \
+    ( (This)->lpVtbl -> AddRef(This) )
+
+#define ISOSMemoryEnum_Release(This)   \
+    ( (This)->lpVtbl -> Release(This) )
+
+
+#define ISOSMemoryEnum_Skip(This,count)        \
+    ( (This)->lpVtbl -> Skip(This,count) )
+
+#define ISOSMemoryEnum_Reset(This)     \
+    ( (This)->lpVtbl -> Reset(This) )
+
+#define ISOSMemoryEnum_GetCount(This,pCount)   \
+    ( (This)->lpVtbl -> GetCount(This,pCount) )
+
+
+#define ISOSMemoryEnum_Next(This,count,memRegion,pNeeded)      \
+    ( (This)->lpVtbl -> Next(This,count,memRegion,pNeeded) )
+
+#endif /* COBJMACROS */
+
+
+#endif         /* C style interface */
+
+
+
+
+#endif         /* __ISOSMemoryEnum_INTERFACE_DEFINED__ */
+
+
 #ifndef __ISOSStackRefEnum_INTERFACE_DEFINED__
 #define __ISOSStackRefEnum_INTERFACE_DEFINED__
 
@@ -3084,7 +3210,7 @@ EXTERN_C const IID IID_ISOSDacInterface13;
 
 #if defined(__cplusplus) && !defined(CINTERFACE)
 
-    MIDL_INTERFACE("3176a8ed-597b-4f54-a71f-83695c6a8c5d")
+    MIDL_INTERFACE("3176a8ed-597b-4f54-a71f-83695c6a8c5e")
     ISOSDacInterface13 : public IUnknown
     {
     public:
@@ -3108,37 +3234,79 @@ EXTERN_C const IID IID_ISOSDacInterface13;
             CLRDATA_ADDRESS *pLoaderHeaps,
             LoaderHeapKind *pKinds,
             int *pNeeded) = 0;
+
+        virtual HRESULT STDMETHODCALLTYPE GetHandleTableMemoryRegions(
+            ISOSMemoryEnum **ppEnum) = 0;
+
+        virtual HRESULT STDMETHODCALLTYPE GetGCBookkeepingMemoryRegions(
+            ISOSMemoryEnum **ppEnum) = 0;
+
+        virtual HRESULT STDMETHODCALLTYPE GetGCFreeRegions(
+            ISOSMemoryEnum **ppEnum) = 0;
+
+        virtual HRESULT STDMETHODCALLTYPE LockedFlush( void) = 0;
     };
 
 
 #else  /* C style interface */
 
+
     typedef struct ISOSDacInterface13Vtbl
     {
         BEGIN_INTERFACE
 
-        DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
         HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
             ISOSDacInterface13 * This,
             /* [in] */ REFIID riid,
             /* [annotation][iid_is][out] */
             _COM_Outptr_  void **ppvObject);
 
-        DECLSPEC_XFGVIRT(IUnknown, AddRef)
         ULONG ( STDMETHODCALLTYPE *AddRef )(
             ISOSDacInterface13 * This);
 
-        DECLSPEC_XFGVIRT(IUnknown, Release)
         ULONG ( STDMETHODCALLTYPE *Release )(
             ISOSDacInterface13 * This);
 
-        DECLSPEC_XFGVIRT(ISOSDacInterface13, TraverseLoaderHeap)
         HRESULT ( STDMETHODCALLTYPE *TraverseLoaderHeap )(
             ISOSDacInterface13 * This,
             CLRDATA_ADDRESS loaderHeapAddr,
             LoaderHeapKind kind,
             VISITHEAP pCallback);
 
+        HRESULT ( STDMETHODCALLTYPE *GetDomainLoaderAllocator )(
+            ISOSDacInterface13 * This,
+            CLRDATA_ADDRESS domainAddress,
+            CLRDATA_ADDRESS *pLoaderAllocator);
+
+        HRESULT ( STDMETHODCALLTYPE *GetLoaderAllocatorHeapNames )(
+            ISOSDacInterface13 * This,
+            int count,
+            const unsigned char **ppNames,
+            int *pNeeded);
+
+        HRESULT ( STDMETHODCALLTYPE *GetLoaderAllocatorHeaps )(
+            ISOSDacInterface13 * This,
+            CLRDATA_ADDRESS loaderAllocator,
+            int count,
+            CLRDATA_ADDRESS *pLoaderHeaps,
+            LoaderHeapKind *pKinds,
+            int *pNeeded);
+
+        HRESULT ( STDMETHODCALLTYPE *GetHandleTableMemoryRegions )(
+            ISOSDacInterface13 * This,
+            ISOSMemoryEnum **ppEnum);
+
+        HRESULT ( STDMETHODCALLTYPE *GetGCBookkeepingMemoryRegions )(
+            ISOSDacInterface13 * This,
+            ISOSMemoryEnum **ppEnum);
+
+        HRESULT ( STDMETHODCALLTYPE *GetGCFreeRegions )(
+            ISOSDacInterface13 * This,
+            ISOSMemoryEnum **ppEnum);
+
+        HRESULT ( STDMETHODCALLTYPE *LockedFlush )(
+            ISOSDacInterface13 * This);
+
         END_INTERFACE
     } ISOSDacInterface13Vtbl;
 
@@ -3176,6 +3344,118 @@ EXTERN_C const IID IID_ISOSDacInterface13;
 #endif         /* __ISOSDacInterface13_INTERFACE_DEFINED__ */
 
 
+#ifndef __ISOSDacInterface14_INTERFACE_DEFINED__
+#define __ISOSDacInterface14_INTERFACE_DEFINED__
+
+/* interface ISOSDacInterface14 */
+/* [uuid][local][object] */ 
+
+
+EXTERN_C const IID IID_ISOSDacInterface14;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+    
+    MIDL_INTERFACE("9aa22aca-6dc6-4a0c-b4e0-70d2416b9837")
+    ISOSDacInterface14 : public IUnknown
+    {
+    public:
+        virtual HRESULT STDMETHODCALLTYPE GetStaticBaseAddress( 
+            CLRDATA_ADDRESS methodTable,
+            CLRDATA_ADDRESS *nonGCStaticsAddress,
+            CLRDATA_ADDRESS *GCStaticsAddress) = 0;
+        
+        virtual HRESULT STDMETHODCALLTYPE GetThreadStaticBaseAddress( 
+            CLRDATA_ADDRESS methodTable,
+            CLRDATA_ADDRESS thread,
+            CLRDATA_ADDRESS *nonGCStaticsAddress,
+            CLRDATA_ADDRESS *GCStaticsAddress) = 0;
+        
+        virtual HRESULT STDMETHODCALLTYPE GetMethodTableInitializationFlags( 
+            CLRDATA_ADDRESS methodTable,
+            MethodTableInitializationFlags *initializationStatus) = 0;
+        
+    };
+    
+    
+#else  /* C style interface */
+
+    typedef struct ISOSDacInterface14Vtbl
+    {
+        BEGIN_INTERFACE
+        
+        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
+            ISOSDacInterface14 * This,
+            /* [in] */ REFIID riid,
+            /* [annotation][iid_is][out] */ 
+            _COM_Outptr_  void **ppvObject);
+        
+        ULONG ( STDMETHODCALLTYPE *AddRef )( 
+            ISOSDacInterface14 * This);
+        
+        ULONG ( STDMETHODCALLTYPE *Release )( 
+            ISOSDacInterface14 * This);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetStaticBaseAddress )( 
+            ISOSDacInterface14 * This,
+            CLRDATA_ADDRESS methodTable,
+            CLRDATA_ADDRESS *nonGCStaticsAddress,
+            CLRDATA_ADDRESS *GCStaticsAddress);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetThreadStaticBaseAddress )( 
+            ISOSDacInterface14 * This,
+            CLRDATA_ADDRESS methodTable,
+            CLRDATA_ADDRESS thread,
+            CLRDATA_ADDRESS *nonGCStaticsAddress,
+            CLRDATA_ADDRESS *GCStaticsAddress);
+        
+        HRESULT ( STDMETHODCALLTYPE *GetMethodTableInitializationFlags )( 
+            ISOSDacInterface14 * This,
+            CLRDATA_ADDRESS methodTable,
+            MethodTableInitializationFlags *initializationStatus);
+        
+        END_INTERFACE
+    } ISOSDacInterface14Vtbl;
+
+    interface ISOSDacInterface14
+    {
+        CONST_VTBL struct ISOSDacInterface14Vtbl *lpVtbl;
+    };
+
+    
+
+#ifdef COBJMACROS
+
+
+#define ISOSDacInterface14_QueryInterface(This,riid,ppvObject) \
+    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 
+
+#define ISOSDacInterface14_AddRef(This)        \
+    ( (This)->lpVtbl -> AddRef(This) ) 
+
+#define ISOSDacInterface14_Release(This)       \
+    ( (This)->lpVtbl -> Release(This) ) 
+
+
+#define ISOSDacInterface14_GetStaticBaseAddress(This,methodTable,nonGCStaticsAddress,GCStaticsAddress) \
+    ( (This)->lpVtbl -> GetStaticBaseAddress(This,methodTable,nonGCStaticsAddress,GCStaticsAddress) ) 
+
+#define ISOSDacInterface14_GetThreadStaticBaseAddress(This,methodTable,thread,nonGCStaticsAddress,GCStaticsAddress)    \
+    ( (This)->lpVtbl -> GetThreadStaticBaseAddress(This,methodTable,thread,nonGCStaticsAddress,GCStaticsAddress) ) 
+
+#define ISOSDacInterface14_GetMethodTableInitializationFlags(This,methodTable,initializationStatus)    \
+    ( (This)->lpVtbl -> GetMethodTableInitializationFlags(This,methodTable,initializationStatus) ) 
+
+#endif /* COBJMACROS */
+
+
+#endif         /* C style interface */
+
+
+
+
+#endif         /* __ISOSDacInterface14_INTERFACE_DEFINED__ */
+
+
 /* Additional Prototypes for ALL interfaces */
 
 /* end of Additional Prototypes */
@@ -3186,3 +3466,4 @@ EXTERN_C const IID IID_ISOSDacInterface13;
 
 #endif
 
+