Complete the !u -il SOS command
authorNeeraj <neerajsharma.9@outlook.com>
Wed, 25 Sep 2019 03:50:50 +0000 (09:20 +0530)
committerAndrew Au <andrewau@microsoft.com>
Wed, 25 Sep 2019 03:50:50 +0000 (20:50 -0700)
src/SOS/Strike/disasm.h
src/SOS/Strike/disasmARM.cpp
src/SOS/Strike/disasmARM64.cpp
src/SOS/Strike/disasmX86.cpp
src/SOS/Strike/exts.h
src/SOS/Strike/sildasm.cpp
src/SOS/Strike/sildasm.h [new file with mode: 0644]
src/SOS/Strike/strike.cpp
src/SOS/Strike/util.h

index 2dfc8d6b223cde49223776fd18327c3c2ab360d5..cec59b5a68b5160757b5fed9214a32d6fac34b33 100644 (file)
@@ -150,7 +150,8 @@ public:
                 GCEncodingInfo * pGCEncodingInfo, 
                 SOSEHInfo *pEHInfo,
                 BOOL bSuppressLines,
-                BOOL bDisplayOffsets) const;
+                BOOL bDisplayOffsets,
+                std::function<void(ULONG*, UINT*, BYTE*)> displayIL) const;
     virtual void IsReturnAddress(
                 TADDR retAddr, 
                 TADDR* whereCalled) const;
@@ -215,7 +216,8 @@ public:
                 GCEncodingInfo *pGCEncodingInfo, 
                 SOSEHInfo *pEHInfo,
                 BOOL bSuppressLines,
-                BOOL bDisplayOffsets) const;
+                BOOL bDisplayOffsets,
+                std::function<void(ULONG*, UINT*, BYTE*)> displayIL) const;
     virtual void IsReturnAddress(
                 TADDR retAddr, 
                 TADDR* whereCalled) const;
@@ -282,7 +284,8 @@ public:
                 GCEncodingInfo *pGCEncodingInfo, 
                 SOSEHInfo *pEHInfo,
                 BOOL bSuppressLines,
-                BOOL bDisplayOffsets) const;
+                BOOL bDisplayOffsets,
+                std::function<void(ULONG*, UINT*, BYTE*)> displayIL) const;
 
     virtual void IsReturnAddress(
                 TADDR retAddr, 
@@ -348,7 +351,8 @@ public:
                 GCEncodingInfo *pGCEncodingInfo, 
                 SOSEHInfo *pEHInfo,
                 BOOL bSuppressLines,
-                BOOL bDisplayOffsets) const;
+                BOOL bDisplayOffsets,
+                std::function<void(ULONG*, UINT*, BYTE*)> displayIL) const;
     virtual void IsReturnAddress(
                 TADDR retAddr, 
                 TADDR* whereCalled) const;
index 1cb5c0ed1ca058b6f2d5d10e394f4bd9b89f34bf..86e40e5a4633de464ca8615e7e03ad0f2270b2c3 100644 (file)
@@ -355,7 +355,8 @@ void ARMMachine::Unassembly (
     GCEncodingInfo *pGCEncodingInfo, 
     SOSEHInfo *pEHInfo,
     BOOL bSuppressLines,
-    BOOL bDisplayOffsets) const
+    BOOL bDisplayOffsets,
+    std::function<void(ULONG*, UINT*, BYTE*)> displayIL) const
 {
     ULONG_PTR PC = PCBegin;
     char line[1024];
@@ -366,6 +367,8 @@ void ARMMachine::Unassembly (
     ULONG curLine = -1;
     WCHAR filename[MAX_LONGPATH];
     ULONG linenum;
+    ULONG ilPosition = 0;
+    UINT ilIndentCount = 0;
 
     while (PC < PCEnd)
     {
@@ -382,6 +385,7 @@ void ARMMachine::Unassembly (
                 ExtOut("\n%S @ %d:\n", filename, linenum);
             }
         }
+        displayIL(&ilPosition, &ilIndentCount, (BYTE*)PC);
 
         //
         // Print out any GC information corresponding to the current instruction offset.
index 499eab9be4a23334cf543307b10d44b644d893c6..f099e3de4069db2408bdb4b8a39ef423bfeaf316 100644 (file)
@@ -149,7 +149,8 @@ void ARM64Machine::Unassembly (
     GCEncodingInfo *pGCEncodingInfo, 
     SOSEHInfo *pEHInfo,
     BOOL bSuppressLines,
-    BOOL bDisplayOffsets) const
+    BOOL bDisplayOffsets,
+    std::function<void(ULONG*, UINT*, BYTE*)> displayIL) const
 {
     TADDR PC = PCBegin;
     char line[1024];
@@ -161,6 +162,8 @@ void ARM64Machine::Unassembly (
     BOOL loBitsSet = FALSE;
     BOOL hiBitsSet = FALSE;
     char *szConstant = NULL;
+    ULONG ilPosition = 0;
+    UINT ilIndentCount = 0;
 
 
     while(PC < PCEnd)
@@ -209,6 +212,7 @@ void ARM64Machine::Unassembly (
                 ExtOut("\n%S @ %d:\n", fileName, lineNum);
             }
         }
+        displayIL(&ilPosition, &ilIndentCount, (BYTE*)PC);
 
         //
         // Print out any GC information corresponding to the current instruction offset.
index afc01a722eb793ca562f834ac20801c89699ba5c..d2b1fda8d3e6107f53479a74ff0db35921382735 100644 (file)
@@ -510,7 +510,8 @@ void
     GCEncodingInfo *pGCEncodingInfo, 
     SOSEHInfo *pEHInfo,
     BOOL bSuppressLines,
-    BOOL bDisplayOffsets) const
+    BOOL bDisplayOffsets,
+    std::function<void(ULONG*, UINT*, BYTE*)> displayIL) const
 {
     ULONG_PTR IP = IPBegin;
     char line[1024];
@@ -524,6 +525,8 @@ void
     ULONG curLine = -1;
     WCHAR filename[MAX_LONGPATH];
     ULONG linenum;
+    ULONG ilPosition = 0;
+    UINT ilIndentCount = 0;
 
     while (IP < IPEnd)
     {
@@ -540,6 +543,7 @@ void
                 ExtOut("\n%S @ %d:\n", filename, linenum);
             }
         }
+        displayIL(&ilPosition, &ilIndentCount, (BYTE*)IP);
 
         //
         // Print out any GC information corresponding to the current instruction offset.
index 61b29e1483567a9cc370ad4c4b56c6d2605ed0b0..606078309191093e0d872a56cf3ca451030dc43e 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <functional>
 
 // wdbgexts.h defines StackTrace which interferes with other parts of the
 // system that use the StackTrace identifier
@@ -351,7 +352,8 @@ public:
                 GCEncodingInfo *pGCEncodingInfo, 
                 SOSEHInfo *pEHInfo,
                 BOOL bSuppressLines,
-                BOOL bDisplayOffsets) const = 0;
+                BOOL bDisplayOffsets,
+                std::function<void(ULONG*, UINT*, BYTE*)> displayIL) const = 0;
 
     // Validates whether retAddr represents a return address by unassembling backwards.
     // If the instruction before retAddr represents a target-specific call instruction
index d0d32eeb18b4f5dd1cd6540812af8184acbae311..e8b93ff39a6b844fa8d2ed06319fa21490d3fb4f 100644 (file)
 #include "corhlpr.h"
 #include "corhlpr.cpp"
 
+#include "sildasm.h"
+
+#include <functional>
+
 //////////////////////////////////////////////////////////////////////////////////////////////////////////
 #undef printf
 #define printf ExtOut
@@ -64,24 +68,21 @@ static OpCode opcodes[] =
 #include "opcode.def"
 };
 
-static ULONG position = 0;
-static BYTE *pBuffer = NULL;
-
 // The UNALIGNED is because on IA64 alignment rules would prevent
 // us from reading a pointer from an unaligned source.
 template <typename T>
-T readData ( ) {
+T ReadData (const BYTE* const pBuffer, ULONG& position) {
     T val = *((T UNALIGNED*)(pBuffer+position));
     position += sizeof(T);
     return val;
 }
 
-unsigned int readOpcode()
+unsigned int ReadOpcode(const BYTE* const pBuffer, ULONG& position)
 {
-    unsigned int c = readData<BYTE>();
+    unsigned int c = ReadData<BYTE>(pBuffer, /* byref */position);
     if (c == 0xFE)
     {
-        c = readData<BYTE>();
+        c = ReadData<BYTE>(pBuffer, /* byref */ position);
         c |= 0x100;
     }
     return c;
@@ -281,22 +282,22 @@ void DisassembleToken(IMetaDataImport *i,
             ULONG cLen;
             WCHAR szName[50];
 
-            if(TypeFromToken(cr) == mdtTypeRef)
+            if (TypeFromToken(cr) == mdtTypeRef)
             {
                 if (FAILED(i->GetTypeRefProps(cr, NULL, szName, 50, &cLen)))
                 {
                     StringCchCopyW(szName, COUNTOF(szName), W("<unknown type ref>"));
                 }
             }
-            else if(TypeFromToken(cr) == mdtTypeDef)
+            else if (TypeFromToken(cr) == mdtTypeDef)
             {
                 if (FAILED(i->GetTypeDefProps(cr, szName, 49, &cLen,
-                                              NULL, NULL)))
+                    NULL, NULL)))
                 {
                     StringCchCopyW(szName, COUNTOF(szName), W("<unknown type def>"));
                 }
             }
-            else if(TypeFromToken(cr) == mdtTypeSpec)
+            else if (TypeFromToken(cr) == mdtTypeSpec)
             {
                 CQuickBytes out;
                 ULONG cSig;
@@ -308,18 +309,45 @@ void DisassembleToken(IMetaDataImport *i,
                 else
                 {
                     PrettyPrintType(sig, &out, i);
-                    MultiByteToWideChar (CP_ACP, 0, asString(&out), -1, szName, 50);
+                    MultiByteToWideChar(CP_ACP, 0, asString(&out), -1, szName, 50);
                 }
             }
             else
             {
                 StringCchCopyW(szName, COUNTOF(szName), W("<unknown type token>"));
             }
-            
+
             printf("%S::%S", szName, pMemberName);
             methodPrettyPrinter.HandleArguments(); // Safe to call in all cases if HandleReturnType hasn't been called. Will do nothing.
         }
         break;
+
+    case mdtString:
+        {
+            ULONG numChars;
+            WCHAR str[84];
+
+            if (i->GetUserString((mdString)token, str, 80, &numChars) == S_OK)
+            {
+                if (numChars < 80)
+                    str[numChars] = 0;
+                wcscpy_s(&str[79], 4, W("..."));
+                WCHAR* ptr = str;
+                while (*ptr != 0) {
+                    if (*ptr < 0x20 || *ptr >= 0x80) {
+                        *ptr = '.';
+                    }
+                    ptr++;
+                }
+
+                printf("\"%S\"", str);
+            }
+            else
+            {
+                printf("STRING %x", token);
+            }
+        }
+        break;
     }
 }
 
@@ -368,160 +396,151 @@ HRESULT DecodeILFromAddress(IMetaDataImport *pImport, TADDR ilAddr)
 
     return Status;
 }
-            
+
 void DecodeIL(IMetaDataImport *pImport, BYTE *buffer, ULONG bufSize)
 {
     // First decode the header
     COR_ILMETHOD *pHeader = (COR_ILMETHOD *) buffer;    
     COR_ILMETHOD_DECODER header(pHeader);    
 
-    // Set globals
-    position = 0;      
-    pBuffer = (BYTE *) header.Code;
+    ULONG position = 0;
+    BYTE* pBuffer = const_cast<BYTE*>(header.Code);
 
     UINT indentCount = 0;
     ULONG endCodePosition = header.GetCodeSize();
-    while(position < endCodePosition)
-    {  
-        for (unsigned e=0;e<header.EHCount();e++)
-        {
-            IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff;
-            const IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehInfo;
-            
-            ehInfo = header.EH->EHClause(e,&ehBuff);
-            if (ehInfo->TryOffset == position)
-            {
-                printf ("%*s.try\n%*s{\n", indentCount, "", indentCount, "");
-                indentCount+=2;
-            }
-            else if ((ehInfo->TryOffset + ehInfo->TryLength) == position)
-            {
-                indentCount-=2;
-                printf("%*s} // end .try\n", indentCount, "");
-            }
 
-            if (ehInfo->HandlerOffset == position)
-            {
-                if (ehInfo->Flags == COR_ILEXCEPTION_CLAUSE_FINALLY)
-                    printf("%*s.finally\n%*s{\n", indentCount, "", indentCount, "");
-                else
-                    printf("%*s.catch\n%*s{\n", indentCount, "", indentCount, "");
+    while (position < endCodePosition)
+    {
+        std::tuple<ULONG, UINT> r = DecodeILAtPosition(
+                pImport, pBuffer, bufSize,
+                position, indentCount, header);
+        position = std::get<0>(r);
+        indentCount = std::get<1>(r);
+        printf("\n");
+    }
+}
 
-                indentCount+=2;
-            }
-            else if ((ehInfo->HandlerOffset + ehInfo->HandlerLength) == position)
-            {
-                indentCount-=2;
-                
-                if (ehInfo->Flags == COR_ILEXCEPTION_CLAUSE_FINALLY)
-                    printf("%*s} // end .finally\n", indentCount, "");
-                else
-                    printf("%*s} // end .catch\n", indentCount, "");
-            }
-        }        
-        
-        printf("%*sIL_%04x: ", indentCount, "", position);
-        unsigned int c = readOpcode();
-        OpCode opcode = opcodes[c];
-        printf("%s ", opcode.name);
+std::tuple<ULONG, UINT> DecodeILAtPosition(
+        IMetaDataImport *pImport, BYTE *pBuffer, ULONG bufSize,
+        ULONG position, UINT indentCount, COR_ILMETHOD_DECODER& header)
+{
+    for (unsigned e=0;e<header.EHCount();e++)
+    {
+        IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff;
+        const IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehInfo;
 
-        switch(opcode.args)
-        {
-        case InlineNone: break;
-        
-        case ShortInlineVar:
-            printf("VAR OR ARG %d",readData<BYTE>()); break;
-        case InlineVar:
-            printf("VAR OR ARG %d",readData<WORD>()); break;
-        case InlineI:
-            printf("%d",readData<LONG>());
-            break;
-        case InlineR:
-            printf("%f",readData<double>());
-            break;
-        case InlineBrTarget:
-            printf("IL_%04x",readData<LONG>() + position); break;
-        case ShortInlineBrTarget:
-            printf("IL_%04x",readData<BYTE>()  + position); break;
-        case InlineI8:
-            printf("%ld", readData<__int64>()); break;
-            
-        case InlineMethod:
-        case InlineField:
-        case InlineType:
-        case InlineTok:
-        case InlineSig:        
+        ehInfo = header.EH->EHClause(e,&ehBuff);
+        if (ehInfo->TryOffset == position)
         {
-            LONG l = readData<LONG>();
-            if (pImport != NULL)
-            {
-                DisassembleToken(pImport, l);
-            }
-            else
-            {
-                printf("TOKEN %x", l); 
-            }
-            break;
+            printf ("%*s.try\n%*s{\n", indentCount, "", indentCount, "");
+            indentCount+=2;
         }
-            
-        case InlineString:
+        else if ((ehInfo->TryOffset + ehInfo->TryLength) == position)
         {
-            LONG l = readData<LONG>();
+            indentCount-=2;
+            printf("%*s} // end .try\n", indentCount, "");
+        }
 
-            ULONG numChars;
-            WCHAR str[84];
+        if (ehInfo->HandlerOffset == position)
+        {
+            if (ehInfo->Flags == COR_ILEXCEPTION_CLAUSE_FINALLY)
+                printf("%*s.finally\n%*s{\n", indentCount, "", indentCount, "");
+            else
+                printf("%*s.catch\n%*s{\n", indentCount, "", indentCount, "");
 
-            if ((pImport != NULL) && (pImport->GetUserString((mdString) l, str, 80, &numChars) == S_OK))
-            {
-                if (numChars < 80)
-                    str[numChars] = 0;
-                wcscpy_s(&str[79], 4, W("..."));
-                WCHAR* ptr = str;
-                while(*ptr != 0) {
-                    if (*ptr < 0x20 || * ptr >= 0x80) {
-                        *ptr = '.';
-                    }
-                    ptr++;
-                }
+            indentCount+=2;
+        }
+        else if ((ehInfo->HandlerOffset + ehInfo->HandlerLength) == position)
+        {
+            indentCount-=2;
 
-                printf("\"%S\"", str);
-            }
+            if (ehInfo->Flags == COR_ILEXCEPTION_CLAUSE_FINALLY)
+                printf("%*s} // end .finally\n", indentCount, "");
             else
-            {
-                printf("STRING %x", l); 
-            }
-            break;
+                printf("%*s} // end .catch\n", indentCount, "");
         }
-            
-        case InlineSwitch:
+    }
+    std::function<void(DWORD)> func = [&pImport](DWORD l) {
+        if (pImport != NULL)
         {
-            LONG cases = readData<LONG>();
-            LONG *pArray = new LONG[cases];
-            LONG i=0;
-            for(i=0;i<cases;i++)
-            {
-                pArray[i] = readData<LONG>();
-            }
-            printf("(");
-            for(i=0;i<cases;i++)
-            {
-                if (i != 0)
-                    printf(", ");
-                printf("IL_%04x",pArray[i] + position);
-            }
-            printf(")");
-            delete [] pArray;
-            break;
+            DisassembleToken(pImport, l);
         }
-        case ShortInlineI:
-            printf("%d", readData<BYTE>()); break;
-        case ShortInlineR:             
-            printf("%f", readData<float>()); break;
-        default: printf("Error, unexpected opcode type\n"); break;
+        else
+        {
+            printf("TOKEN %x", l);
         }
+    };
+    position = DisplayILOperation(indentCount, pBuffer, position, func);
+    return std::make_tuple(position, indentCount);
+}
 
-        printf("\n");
+ULONG DisplayILOperation(const UINT indentCount, BYTE *pBuffer, ULONG position, std::function<void(DWORD)>& disassembleTokenFunc)
+{
+    printf("%*sIL_%04x: ", indentCount, "", position);
+    unsigned int c = ReadOpcode(pBuffer, position);
+    OpCode opcode = opcodes[c];
+    printf("%s ", opcode.name);
+
+    switch (opcode.args)
+    {
+    case InlineNone: break;
+
+    case ShortInlineVar:
+        printf("VAR OR ARG %d", ReadData<BYTE>(pBuffer, /* byref */ position)); break;
+    case InlineVar:
+        printf("VAR OR ARG %d", ReadData<WORD>(pBuffer, /* byref */ position)); break;
+    case InlineI:
+        printf("%d", ReadData<LONG>(pBuffer, /* byref */ position));
+        break;
+    case InlineR:
+        printf("%f", ReadData<double>(pBuffer, /* byref */ position));
+        break;
+    case InlineBrTarget:
+        printf("IL_%04x", ReadData<LONG>(pBuffer, /* byref */ position) + position); break;
+    case ShortInlineBrTarget:
+        printf("IL_%04x", ReadData<BYTE>(pBuffer, /* byref */ position) + position); break;
+    case InlineI8:
+        printf("%ld", ReadData<__int64>(pBuffer, /* byref */ position)); break;
+
+    case InlineMethod:
+    case InlineField:
+    case InlineType:
+    case InlineTok:
+    case InlineSig:
+    case InlineString:
+    {
+        LONG l = ReadData<LONG>(pBuffer, /* byref */ position);
+        disassembleTokenFunc(l);
+        break;
+    }
+
+    case InlineSwitch:
+    {
+        LONG cases = ReadData<LONG>(pBuffer, /* byref */ position);
+        LONG* pArray = new LONG[cases];
+        LONG i = 0;
+        for (i = 0;i<cases;i++)
+        {
+            pArray[i] = ReadData<LONG>(pBuffer, /* byref */ position);
+        }
+        printf("(");
+        for (i = 0;i<cases;i++)
+        {
+            if (i != 0)
+                printf(", ");
+            printf("IL_%04x", pArray[i] + position);
+        }
+        printf(")");
+        delete[] pArray;
+        break;
     }
+    case ShortInlineI:
+        printf("%d", ReadData<BYTE>(pBuffer, /* byref */ position)); break;
+    case ShortInlineR:
+        printf("%f", ReadData<float>(pBuffer, /* byref */ position)); break;
+    default: printf("Error, unexpected opcode type\n"); break;
+    }
+    return position;
 }
 
 DWORD_PTR GetObj(DacpObjectData& tokenArray, UINT item)
@@ -622,80 +641,18 @@ void DisassembleToken(DacpObjectData& tokenArray,
 void DecodeDynamicIL(BYTE *data, ULONG Size, DacpObjectData& tokenArray)
 {
     // There is no header for this dynamic guy.
-    // Set globals
-    position = 0;      
-    pBuffer = data;
+    ULONG position = 0;
+    BYTE *pBuffer = data;
 
     // At this time no exception information will be displayed (fix soon)
     UINT indentCount = 0;
     ULONG endCodePosition = Size;
     while(position < endCodePosition)
-    {          
-        printf("%*sIL_%04x: ", indentCount, "", position);
-        unsigned int c = readOpcode();
-        OpCode opcode = opcodes[c];
-        printf("%s ", opcode.name);
-
-        switch(opcode.args)
-        {
-        case InlineNone: break;
-        
-        case ShortInlineVar:
-            printf("VAR OR ARG %d",readData<BYTE>()); break;
-        case InlineVar:
-            printf("VAR OR ARG %d",readData<WORD>()); break;
-        case InlineI:
-            printf("%d",readData<LONG>());
-            break;
-        case InlineR:
-            printf("%f",readData<double>());
-            break;
-        case InlineBrTarget:
-            printf("IL_%04x",readData<LONG>() + position); break;
-        case ShortInlineBrTarget:
-            printf("IL_%04x",readData<BYTE>()  + position); break;
-        case InlineI8:
-            printf("%ld", readData<__int64>()); break;
-            
-        case InlineMethod:
-        case InlineField:
-        case InlineType:
-        case InlineTok:
-        case InlineSig:        
-        case InlineString:            
-        {
-            LONG l = readData<LONG>();
-            DisassembleToken(tokenArray, l);            
-            break;
-        }
-                        
-        case InlineSwitch:
-        {
-            LONG cases = readData<LONG>();
-            LONG *pArray = new LONG[cases];
-            LONG i=0;
-            for(i=0;i<cases;i++)
-            {
-                pArray[i] = readData<LONG>();
-            }
-            printf("(");
-            for(i=0;i<cases;i++)
-            {
-                if (i != 0)
-                    printf(", ");
-                printf("IL_%04x",pArray[i] + position);
-            }
-            printf(")");
-            delete [] pArray;
-            break;
-        }
-        case ShortInlineI:
-            printf("%d", readData<BYTE>()); break;
-        case ShortInlineR:             
-            printf("%f", readData<float>()); break;
-        default: printf("Error, unexpected opcode type\n"); break;
-        }
-
+    {
+        std::function<void(DWORD)> func = [&tokenArray](DWORD l) {
+            DisassembleToken(tokenArray, l);
+        };
+        position = DisplayILOperation(indentCount, pBuffer, position, func);
         printf("\n");
     }
 }
@@ -709,7 +666,7 @@ static char* asString(CQuickBytes *out) {
     out->ReSize(oldSize + 1);
     char* cur = &((char*) out->Ptr())[oldSize]; 
     *cur = 0;   
-    out->ReSize(oldSize);              // Don't count the null character
+    out->ReSize(oldSize);           // Don't count the null character
     return((char*) out->Ptr()); 
 }
 
@@ -948,7 +905,7 @@ PCCOR_SIGNATURE PrettyPrintType(
               break;
             }
 
-            case ELEMENT_TYPE_PINNED   :
+            case ELEMENT_TYPE_PINNED:
                 str = " pinned"; goto MODIFIER;
             case ELEMENT_TYPE_PTR           :
                 str = "*"; goto MODIFIER;
@@ -1008,7 +965,7 @@ swprintf_s(sz,16,W("$%s$%X"),szStdNamePrefix[tk>>24],tk&0x00FFFFFF); psz = sz; }
 
 const char* PrettyPrintClass(
     CQuickBytes *out,                   // where to put the pretty printed string   
-    mdToken tk,                                                        // The class token to look up 
+    mdToken tk,                         // The class token to look up 
     IMetaDataImport *pIMD,           // ptr to IMetaDataImport class with ComSig
     DWORD formatFlags /*= formatILDasm*/)
 {
@@ -1109,7 +1066,7 @@ const char* PrettyPrintClass(
 
         case mdtAssemblyRef:
             {
-                LPCSTR szName = NULL;
+                LPCSTR szName = NULL;
                 ULONG unused;
                 ToRelease<IMetaDataAssemblyImport> pAsmImport;
                 if (SUCCEEDED(pIMD->QueryInterface(IID_IMetaDataAssemblyImport, (LPVOID *)&pAsmImport)))
diff --git a/src/SOS/Strike/sildasm.h b/src/SOS/Strike/sildasm.h
new file mode 100644 (file)
index 0000000..fffc021
--- /dev/null
@@ -0,0 +1,22 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// ==++==
+// 
+// 
+// ==--==
+#ifndef __sildasm_h__
+#define __sildasm_h__
+
+#define _BLD_CLR 1
+#include "corhlpr.h"
+#include "daccess.h"
+#include "dacprivate.h"
+
+std::tuple<ULONG, UINT> DecodeILAtPosition(
+        IMetaDataImport *pImport, BYTE *buffer, ULONG bufSize,
+        ULONG position, UINT indentCount, COR_ILMETHOD_DECODER& header);
+
+#endif // __sildasm_h__
index d8207eeaba61cf2d1967b8d1719bffcd226c91c2..d3e0d55ee7862c5f1dd4e20d3e1a32ff5016899d 100644 (file)
@@ -85,6 +85,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stddef.h>
+#include <stdexcept>
+#include <deque>
 
 #include "strike.h"
 #include "sos.h"
@@ -153,6 +155,9 @@ const UINT kcMaxMethodDescsForProfiler = 100;
 #include <set>
 #include <vector>
 #include <map>
+#include <tuple>
+#include <memory>
+#include <functional>
 
 BOOL CallStatus;
 BOOL ControlC = FALSE;
@@ -835,6 +840,15 @@ BOOL GatherDynamicInfo(TADDR DynamicMethodObj, DacpObjectData *codeArray,
     return bRet;
 }
 
+typedef std::tuple<TADDR, IMetaDataImport* > GetILAddressResult;
+GetILAddressResult GetILAddress(const DacpMethodDescData& MethodDescData);
+
+/**********************************************************************\
+* Routine Description:                                                 *
+*                                                                      *
+*    Displays the Microsoft intermediate language (MSIL) that is       *
+*    associated with a managed method.                                 *
+\**********************************************************************/
 DECLARE_API(DumpIL)
 {
     INIT_API();
@@ -904,64 +918,15 @@ DECLARE_API(DumpIL)
         }
         else
         {
-            TADDR ilAddr = NULL;
-            struct DacpProfilerILData ilData;
-            ReleaseHolder<ISOSDacInterface7> sos7;
-            if (SUCCEEDED(g_sos->QueryInterface(__uuidof(ISOSDacInterface7), &sos7)) && 
-                SUCCEEDED(sos7->GetProfilerModifiedILInformation(MethodDescData.MethodDescPtr, &ilData)))
-            {
-                if (ilData.type == DacpProfilerILData::ILModified)
-                {
-                    ExtOut("Found profiler modified IL\n");
-                    ilAddr = TO_TADDR(ilData.il);
-                }
-            }
-
-            // Factor this so that it returns a map from IL offset to the textual representation of the decoding
-            // to be consumed by !u -il
-            // The disassemble function can give a MethodDescData as well as the set of keys IL offsets
-
-            // This is not a dynamic method, print the IL for it.
-            // Get the module
-            DacpModuleData dmd;    
-            if (dmd.Request(g_sos, MethodDescData.ModulePtr) != S_OK)
+            GetILAddressResult result = GetILAddress(MethodDescData);
+            if (std::get<0>(result) == NULL)
             {
-                ExtOut("Unable to get module\n");
-                return Status;
-            }
-
-            ToRelease<IMetaDataImport> pImport = MDImportForModule(&dmd);
-            if (pImport == NULL)
-            {
-                ExtOut("bad import\n");
-                return Status;
-            }
-
-            if (ilAddr == NULL)
-            { 
-                ULONG pRva;
-                DWORD dwFlags;
-                if (pImport->GetRVA(MethodDescData.MDToken, &pRva, &dwFlags) != S_OK)
-                {
-                    ExtOut("error in import\n");
-                    return Status;
-                }    
-
-                CLRDATA_ADDRESS ilAddrClr;
-                if (g_sos->GetILForModule(MethodDescData.ModulePtr, pRva, &ilAddrClr) != S_OK)
-                {
-                    ExtOut("FindIL failed\n");
-                    return Status;
-                }
-
-                ilAddr = TO_TADDR(ilAddrClr);
-            }
-
-            if (ilAddr == NULL)
-            {
-                ExtOut("Unkown error in reading function IL\n");
+                ExtOut("ilAddr is %p\n", SOS_PTR(std::get<0>(result)));
                 return E_FAIL;
             }
+            ExtOut("ilAddr is %p pImport is %p\n", SOS_PTR(std::get<0>(result)), SOS_PTR(std::get<1>(result)));
+            TADDR ilAddr = std::get<0>(result);
+            ToRelease<IMetaDataImport> pImport(std::get<1>(result));
             IfFailRet(DecodeILFromAddress(pImport, ilAddr));
         }
     }
@@ -2290,6 +2255,8 @@ struct StackTraceElement
 
 #include "sos_stacktrace.h"
 
+#include "sildasm.h"
+
 class StringOutput
 {
 public:
@@ -4454,14 +4421,14 @@ void ExtOutTaskStateFlagsDescription(int stateFlags)
 
 void ExtOutStateMachineFields(AsyncRecord& ar)
 {
-       DacpMethodTableData mtabledata;
-       DacpMethodTableFieldData vMethodTableFields;
-       if (mtabledata.Request(g_sos, ar.StateMachineMT) == S_OK &&
-               vMethodTableFields.Request(g_sos, ar.StateMachineMT) == S_OK &&
-               vMethodTableFields.wNumInstanceFields + vMethodTableFields.wNumStaticFields > 0)
-       {
-               DisplayFields(ar.StateMachineMT, &mtabledata, &vMethodTableFields, (DWORD_PTR)ar.StateMachineAddr, TRUE, ar.IsValueType);
-       }
+    DacpMethodTableData mtabledata;
+    DacpMethodTableFieldData vMethodTableFields;
+    if (mtabledata.Request(g_sos, ar.StateMachineMT) == S_OK &&
+        vMethodTableFields.Request(g_sos, ar.StateMachineMT) == S_OK &&
+        vMethodTableFields.wNumInstanceFields + vMethodTableFields.wNumStaticFields > 0)
+    {
+        DisplayFields(ar.StateMachineMT, &mtabledata, &vMethodTableFields, (DWORD_PTR)ar.StateMachineAddr, TRUE, ar.IsValueType);
+    }
 }
 
 void FindStateMachineTypes(DWORD_PTR* corelibModule, mdTypeDef* stateMachineBox, mdTypeDef* debugStateMachineBox, mdTypeDef* task)
@@ -4828,8 +4795,8 @@ DECLARE_API(DumpAsync)
                             sos::MethodTable contMT = TO_TADDR(contAsyncRecord->second.StateMachineMT);
                             if (contAsyncRecord->second.IsStateMachine) ExtOut("(%d) ", contAsyncRecord->second.StateValue);
                             ExtOut("%S\n", contMT.GetName());
-                                                       if (contAsyncRecord->second.IsStateMachine && dumpFields) ExtOutStateMachineFields(contAsyncRecord->second);
-                                               }
+                            if (contAsyncRecord->second.IsStateMachine && dumpFields) ExtOutStateMachineFields(contAsyncRecord->second);
+                        }
                         else
                         {
                             ExtOut("%S\n", cont.GetTypeName());
@@ -9179,6 +9146,80 @@ GetClrMethodInstance(
     ___in ULONG64 NativeOffset,
     ___out IXCLRDataMethodInstance** Method);
 
+typedef std::tuple<DacpMethodDescData, DacpCodeHeaderData, HRESULT> ExtractionCodeHeaderResult;
+
+ExtractionCodeHeaderResult extractCodeHeaderData(DWORD_PTR methodDesc, DWORD_PTR dwStartAddr);
+HRESULT displayGcInfo(BOOL fWithGCInfo, const DacpCodeHeaderData& codeHeaderData);
+HRESULT GetIntermediateLangMap(BOOL bIL, const DacpCodeHeaderData& codeHeaderData,
+                               std::unique_ptr<CLRDATA_IL_ADDRESS_MAP[]>& map,
+                               ULONG32& mapCount,
+                               BOOL dumpMap);
+
+GetILAddressResult GetILAddress(const DacpMethodDescData& MethodDescData)
+{
+    GetILAddressResult error = std::make_tuple(NULL, nullptr);
+    TADDR ilAddr = NULL;
+    struct DacpProfilerILData ilData;
+    ReleaseHolder<ISOSDacInterface7> sos7;
+    if (SUCCEEDED(g_sos->QueryInterface(__uuidof(ISOSDacInterface7), &sos7)) &&
+        SUCCEEDED(sos7->GetProfilerModifiedILInformation(MethodDescData.MethodDescPtr, &ilData)))
+    {
+        if (ilData.type == DacpProfilerILData::ILModified)
+        {
+            ExtOut("Found profiler modified IL\n");
+            ilAddr = TO_TADDR(ilData.il);
+        }
+    }
+
+    // Factor this so that it returns a map from IL offset to the textual representation of the decoding
+    // to be consumed by !u -il
+    // The disassemble function can give a MethodDescData as well as the set of keys IL offsets
+
+    // This is not a dynamic method, print the IL for it.
+    // Get the module
+    DacpModuleData dmd;    
+    if (dmd.Request(g_sos, MethodDescData.ModulePtr) != S_OK)
+    {
+        ExtOut("Unable to get module\n");
+        return error;
+    }
+
+    ToRelease<IMetaDataImport> pImport(MDImportForModule(&dmd));
+    if (pImport == NULL)
+    {
+        ExtOut("bad import\n");
+        return error;
+    }
+
+    if (ilAddr == NULL)
+    { 
+        ULONG pRva;
+        DWORD dwFlags;
+        if (pImport->GetRVA(MethodDescData.MDToken, &pRva, &dwFlags) != S_OK)
+        {
+            ExtOut("error in import\n");
+            return error;
+        }    
+
+        CLRDATA_ADDRESS ilAddrClr;
+        if (g_sos->GetILForModule(MethodDescData.ModulePtr, pRva, &ilAddrClr) != S_OK)
+        {
+            ExtOut("FindIL failed\n");
+            return error;
+        }
+
+        ilAddr = TO_TADDR(ilAddrClr);
+    }
+
+    if (ilAddr == NULL)
+    {
+        ExtOut("Unknown error in reading function IL\n");
+        return error;
+    }
+    GetILAddressResult result = std::make_tuple(ilAddr, pImport.Detach());
+    return result;
+}
+
 /**********************************************************************\
 * Routine Description:                                                 *
 *                                                                      *
@@ -9249,8 +9290,247 @@ DECLARE_API(u)
         }
     }
 
+    ExtractionCodeHeaderResult p = extractCodeHeaderData(methodDesc, dwStartAddr);
+    Status = std::get<2>(p);
+    if (Status != S_OK)
+    {
+        return Status;
+    }
+
+    NameForMD_s(methodDesc, g_mdName, mdNameLen);
+    ExtOut("%S\n", g_mdName);
+
+    DacpMethodDescData& MethodDescData = std::get<0>(p);
+    DacpCodeHeaderData& codeHeaderData = std::get<1>(p);
+    std::unique_ptr<CLRDATA_IL_ADDRESS_MAP[]> map(nullptr);
+    ULONG32 mapCount = 0;
+    Status = GetIntermediateLangMap(bIL, codeHeaderData, map /*out*/, mapCount /* out */, false);
+    if (Status != S_OK)
+    {
+        return Status;
+    }
+
+    // ///////////////////////////////////////////////////////////////////////////
+    // This can be reused with sildasm but kept as-is largely since it just
+    // works so it can be fixed later.
+    // ///////////////////////////////////////////////////////////////////////////
+
+    if (MethodDescData.bIsDynamic && MethodDescData.managedDynamicMethodObject)
+    {
+        ExtOut("Can only work with dynamic not implemented\n");
+        return Status;
+    }
+
+    GetILAddressResult result = GetILAddress(MethodDescData);
+    if (std::get<0>(result) == NULL)
+    {
+        ExtOut("ilAddr is %p\n", SOS_PTR(std::get<0>(result)));
+        return E_FAIL;
+    }
+    ExtOut("ilAddr is %p pImport is %p\n", SOS_PTR(std::get<0>(result)), SOS_PTR(std::get<1>(result)));
+    TADDR ilAddr = std::get<0>(result);
+    ToRelease<IMetaDataImport> pImport(std::get<1>(result));
+
+    /// Taken from DecodeILFromAddress(IMetaDataImport *pImport, TADDR ilAddr)
+    ULONG Size = GetILSize(ilAddr);
+    if (Size == 0)
+    {
+        ExtOut("error decoding IL\n");
+        return Status;
+    }
+    // Read the memory into a local buffer
+    ArrayHolder<BYTE> pArray = new BYTE[Size];
+    Status = g_ExtData->ReadVirtual(TO_CDADDR(ilAddr), pArray, Size, NULL);
+    if (Status != S_OK)
+    {
+        ExtOut("Failed to read memory\n");
+        return Status;
+    }
+    /// Taken from DecodeIL(pImport, pArray, Size);
+    // First decode the header
+    BYTE *buffer = pArray;
+    ULONG bufSize = Size;
+    COR_ILMETHOD *pHeader = (COR_ILMETHOD *) buffer;
+    COR_ILMETHOD_DECODER header(pHeader);
+    ULONG position = 0;
+    BYTE* pBuffer = const_cast<BYTE*>(header.Code);
+    UINT indentCount = 0;
+    ULONG endCodePosition = header.GetCodeSize();
+    struct ILLocationRange {
+        ULONG mStartPosition;
+        ULONG mEndPosition;
+        BYTE* mStartAddress;
+        BYTE* mEndAddress;
+    };
+    std::deque<ILLocationRange> ilCodePositions;
+
+    if (mapCount > 0)
+    {
+        while (position < endCodePosition)
+        {
+            ULONG mapIndex = 0;
+            do
+            {
+                while ((mapIndex < mapCount) && (position != map[mapIndex].ilOffset))
+                {
+                    ++mapIndex;
+                }
+                if (map[mapIndex].endAddress > map[mapIndex].startAddress)
+                {
+                    break;
+                }
+                ++mapIndex;
+            } while (mapIndex < mapCount);
+            std::tuple<ULONG, UINT> r = DecodeILAtPosition(
+                pImport, pBuffer, bufSize,
+                position, indentCount, header);
+            ExtOut("\n");
+            if (mapIndex < mapCount)
+            {
+                ILLocationRange entry = {
+                    position,
+                    std::get<0>(r) - 1,
+                    (BYTE*)map[mapIndex].startAddress,
+                    (BYTE*)map[mapIndex].endAddress
+                };
+                ilCodePositions.push_back(std::move(entry));
+            }
+            else
+            {
+                if (!ilCodePositions.empty())
+                {
+                    auto& entry = ilCodePositions.back();
+                    entry.mEndPosition = position;
+                }
+            }
+            position = std::get<0>(r);
+            indentCount = std::get<1>(r);
+        }
+    }
+
+    position = 0;
+    indentCount = 0;
+    std::function<void(ULONG*, UINT*, BYTE*)> displayILFun =
+        [&pImport, &pBuffer, bufSize, &header, &ilCodePositions](ULONG *pPosition, UINT *pIndentCount,
+                                                BYTE *pIp) -> void {
+                for (auto iter = ilCodePositions.begin(); iter != ilCodePositions.end(); ++iter)
+                {
+                    if ((pIp >= iter->mStartAddress) && (pIp < iter->mEndAddress))
+                    {
+                        ULONG position = iter->mStartPosition;
+                        ULONG endPosition = iter->mEndPosition;
+                        while (position <= endPosition)
+                        {
+                            std::tuple<ULONG, UINT> r = DecodeILAtPosition(
+                                pImport, pBuffer, bufSize,
+                                position, *pIndentCount, header);
+                            ExtOut("\n");
+                            position = std::get<0>(r);
+                            *pIndentCount = std::get<1>(r);
+                        }
+                        ilCodePositions.erase(iter);
+                        break;
+                    }
+                }
+    };
+
+    if (codeHeaderData.ColdRegionStart != NULL)
+    {
+        ExtOut("Begin %p, size %x. Cold region begin %p, size %x\n",
+            SOS_PTR(codeHeaderData.MethodStart), codeHeaderData.HotRegionSize,
+            SOS_PTR(codeHeaderData.ColdRegionStart), codeHeaderData.ColdRegionSize);
+    }
+    else
+    {
+        ExtOut("Begin %p, size %x\n", SOS_PTR(codeHeaderData.MethodStart), codeHeaderData.MethodSize);
+    }
+
+    Status = displayGcInfo(fWithGCInfo, codeHeaderData);
+    if (Status != S_OK)
+    {
+        return Status;
+    }
+
+    SOSEHInfo *pInfo = NULL;
+    if (fWithEHInfo)
+    {
+        pInfo = new NOTHROW SOSEHInfo;
+        if (pInfo == NULL)
+        {
+            ReportOOM();                
+        }
+        else if (g_sos->TraverseEHInfo(codeHeaderData.MethodStart, gatherEh, (LPVOID)pInfo) != S_OK)
+        {
+            ExtOut("Failed to gather EHInfo data\n");
+            delete pInfo;
+            pInfo = NULL;            
+        }
+    }
+
+    if (codeHeaderData.ColdRegionStart == NULL)
+    {
+        g_targetMachine->Unassembly (
+                (DWORD_PTR) codeHeaderData.MethodStart,
+                ((DWORD_PTR)codeHeaderData.MethodStart) + codeHeaderData.MethodSize,
+                dwStartAddr,
+                (DWORD_PTR) MethodDescData.GCStressCodeCopy,
+                fWithGCInfo ? &g_gcEncodingInfo : NULL,
+                pInfo,
+                bSuppressLines,
+                bDisplayOffsets,
+                displayILFun);
+    }
+    else
+    {
+        ExtOut("Hot region:\n");
+        g_targetMachine->Unassembly (
+                (DWORD_PTR) codeHeaderData.MethodStart,
+                ((DWORD_PTR)codeHeaderData.MethodStart) + codeHeaderData.HotRegionSize,
+                dwStartAddr,
+                (DWORD_PTR) MethodDescData.GCStressCodeCopy,
+                fWithGCInfo ? &g_gcEncodingInfo : NULL,
+                pInfo,
+                bSuppressLines,
+                bDisplayOffsets,
+                displayILFun);
+
+        ExtOut("Cold region:\n");
+        
+        // Displaying gcinfo for a cold region requires knowing the size of
+        // the hot region preceeding.
+        g_gcEncodingInfo.hotSizeToAdd = codeHeaderData.HotRegionSize;
+
+        g_targetMachine->Unassembly (
+                (DWORD_PTR) codeHeaderData.ColdRegionStart,
+                ((DWORD_PTR)codeHeaderData.ColdRegionStart) + codeHeaderData.ColdRegionSize,
+                dwStartAddr,
+                ((DWORD_PTR) MethodDescData.GCStressCodeCopy) + codeHeaderData.HotRegionSize,                
+                fWithGCInfo ? &g_gcEncodingInfo : NULL,
+                pInfo,
+                bSuppressLines,
+                bDisplayOffsets,
+                displayILFun);
+
+    }
+
+    if (pInfo)
+    {
+        delete pInfo;
+        pInfo = NULL;
+    }
+
+    if (fWithGCInfo)
+    {
+        g_gcEncodingInfo.Deinitialize();
+    }
+    
+    return Status;
+}
+
+inline ExtractionCodeHeaderResult extractCodeHeaderData(DWORD_PTR methodDesc, DWORD_PTR dwStartAddr)
+{
     DacpMethodDescData MethodDescData;
-    Status =
+    HRESULT Status =
         g_sos->GetMethodDescData(
             TO_CDADDR(methodDesc),
             dwStartAddr == methodDesc ? NULL : dwStartAddr,
@@ -9261,13 +9541,13 @@ DECLARE_API(u)
     if (Status != S_OK)
     {
         ExtOut("Failed to get method desc for %p.\n", SOS_PTR(dwStartAddr));
-        return Status;
-    }    
+        return ExtractionCodeHeaderResult(std::move(MethodDescData), DacpCodeHeaderData(), Status);
+    }
 
     if (!MethodDescData.bHasNativeCode)
     {
         ExtOut("Not jitted yet\n");
-        return Status;
+        return ExtractionCodeHeaderResult(std::move(MethodDescData), DacpCodeHeaderData(), S_FALSE);
     }
 
     // Get the appropriate code header. If we were passed an MD, then use
@@ -9276,26 +9556,25 @@ DECLARE_API(u)
     // disassemble the rejit version that the user explicitly specified with their IP.
     DacpCodeHeaderData codeHeaderData;
     if (codeHeaderData.Request(
-        g_sos, 
+        g_sos,
         TO_CDADDR(
-            (dwStartAddr == methodDesc) ? MethodDescData.NativeCodeAddr : dwStartAddr)
-            ) != S_OK)
-
+        (dwStartAddr == methodDesc) ? MethodDescData.NativeCodeAddr : dwStartAddr)
+    ) != S_OK)
     {
         ExtOut("Unable to get codeHeader information\n");
-        return Status;
-    }                
-    
+        return ExtractionCodeHeaderResult(std::move(MethodDescData), DacpCodeHeaderData(), S_FALSE);
+    }
+
     if (codeHeaderData.MethodStart == 0)
     {
         ExtOut("not a valid MethodDesc\n");
-        return Status;
+        return ExtractionCodeHeaderResult(std::move(MethodDescData), DacpCodeHeaderData(), S_FALSE);
     }
-    
+
     if (codeHeaderData.JITType == TYPE_UNKNOWN)
     {
         ExtOut("unknown Jit\n");
-        return Status;
+        return ExtractionCodeHeaderResult(std::move(MethodDescData), DacpCodeHeaderData(), S_FALSE);
     }
     else if (codeHeaderData.JITType == TYPE_JIT)
     {
@@ -9305,58 +9584,11 @@ DECLARE_API(u)
     {
         ExtOut("preJIT generated code\n");
     }
+    return ExtractionCodeHeaderResult(std::move(MethodDescData), std::move(codeHeaderData), S_OK);
+}
 
-    NameForMD_s(methodDesc, g_mdName, mdNameLen);
-    ExtOut("%S\n", g_mdName);
-
-    if (bIL)
-    {
-        ToRelease<IXCLRDataMethodInstance> pMethodInst(NULL);
-
-        if ((Status = GetClrMethodInstance(codeHeaderData.MethodStart, &pMethodInst)) != S_OK)
-        {
-            return Status;
-        }
-
-        ArrayHolder<CLRDATA_IL_ADDRESS_MAP> map(nullptr);
-        ULONG32 mapCount = 0;
-
-        if ((Status = pMethodInst->GetILAddressMap(mapCount, &mapCount, map)) != S_OK)
-        {
-            return Status;
-        }
-
-        map = new NOTHROW CLRDATA_IL_ADDRESS_MAP[mapCount];
-        if (map == NULL)
-        {
-            ReportOOM();
-            return E_OUTOFMEMORY;
-        }
-
-        if ((Status = pMethodInst->GetILAddressMap(mapCount, &mapCount, map)) != S_OK)
-        {
-            return Status;
-        }
-
-        for (ULONG32 i = 0; i < mapCount; i++)
-        {
-            // TODO: These information should be interleaved with the disassembly
-            // Decoded IL can be obtained through refactoring DumpIL code.
-            ExtOut("%04x %p %p\n", map[i].ilOffset, map[i].startAddress, map[i].endAddress);
-        }
-    }
-
-    if (codeHeaderData.ColdRegionStart != NULL)
-    {
-        ExtOut("Begin %p, size %x. Cold region begin %p, size %x\n",
-            SOS_PTR(codeHeaderData.MethodStart), codeHeaderData.HotRegionSize,
-            SOS_PTR(codeHeaderData.ColdRegionStart), codeHeaderData.ColdRegionSize);
-    }
-    else
-    {
-        ExtOut("Begin %p, size %x\n", SOS_PTR(codeHeaderData.MethodStart), codeHeaderData.MethodSize);
-    }
-
+HRESULT displayGcInfo(BOOL fWithGCInfo, const DacpCodeHeaderData& codeHeaderData)
+{
     //
     // Set up to mix gc info with the code if requested. To do this, we first generate all the textual
     // gc info up front. This text is the same as the "!gcinfo" command, and looks like:
@@ -9446,13 +9678,13 @@ DECLARE_API(u)
             ExtOut("Could not allocate memory to read the gc info.\n");
             return E_OUTOFMEMORY;
         }
-        
-        memset (table, 0, tableSize);
+
+        memset(table, 0, tableSize);
         // We avoid using move here, because we do not want to return
         if (!SafeReadMemory(TO_TADDR(codeHeaderData.GCInfo), table, tableSize, NULL))
         {
             ExtOut("Could not read memory %p\n", SOS_PTR(codeHeaderData.GCInfo));
-            return Status;
+            return ERROR_INVALID_DATA;
         }
 
         //
@@ -9464,85 +9696,56 @@ DECLARE_API(u)
         {
             return E_OUTOFMEMORY;
         }
-        
+
         GCInfoToken gcInfoToken = { table, GCINFO_VERSION };
         g_targetMachine->DumpGCInfo(gcInfoToken, methodSize, DecodeGCTableEntry, false /*encBytes*/, false /*bPrintHeader*/);
-    }    
+    }
+    return S_OK;
+}
 
-    SOSEHInfo *pInfo = NULL;
-    if (fWithEHInfo)
+HRESULT GetIntermediateLangMap(BOOL bIL, const DacpCodeHeaderData& codeHeaderData,
+                               std::unique_ptr<CLRDATA_IL_ADDRESS_MAP[]>& map,
+                               ULONG32& mapCount,
+                               BOOL dumpMap)
+{
+    HRESULT Status = S_OK;
+    if (bIL)
     {
-        pInfo = new NOTHROW SOSEHInfo;
-        if (pInfo == NULL)
+        ToRelease<IXCLRDataMethodInstance> pMethodInst(NULL);
+
+        if ((Status = GetClrMethodInstance(codeHeaderData.MethodStart, &pMethodInst)) != S_OK)
         {
-            ReportOOM();                
+            return Status;
         }
-        else if (g_sos->TraverseEHInfo(codeHeaderData.MethodStart, gatherEh, (LPVOID)pInfo) != S_OK)
+
+        if ((Status = pMethodInst->GetILAddressMap(mapCount, &mapCount, map.get())) != S_OK)
         {
-            ExtOut("Failed to gather EHInfo data\n");
-            delete pInfo;
-            pInfo = NULL;            
+            return Status;
         }
-    }
-    
-    if (codeHeaderData.ColdRegionStart == NULL)
-    {
-        g_targetMachine->Unassembly (
-                (DWORD_PTR) codeHeaderData.MethodStart,
-                ((DWORD_PTR)codeHeaderData.MethodStart) + codeHeaderData.MethodSize,
-                dwStartAddr,
-                (DWORD_PTR) MethodDescData.GCStressCodeCopy,
-                fWithGCInfo ? &g_gcEncodingInfo : NULL,
-                pInfo,
-                bSuppressLines,
-                bDisplayOffsets
-                );
-    }
-    else
-    {
-        ExtOut("Hot region:\n");
-        g_targetMachine->Unassembly (
-                (DWORD_PTR) codeHeaderData.MethodStart,
-                ((DWORD_PTR)codeHeaderData.MethodStart) + codeHeaderData.HotRegionSize,
-                dwStartAddr,
-                (DWORD_PTR) MethodDescData.GCStressCodeCopy,
-                fWithGCInfo ? &g_gcEncodingInfo : NULL,
-                pInfo,
-                bSuppressLines,
-                bDisplayOffsets
-                );
-
-        ExtOut("Cold region:\n");
-        
-        // Displaying gcinfo for a cold region requires knowing the size of
-        // the hot region preceeding.
-        g_gcEncodingInfo.hotSizeToAdd = codeHeaderData.HotRegionSize;
 
-        g_targetMachine->Unassembly (
-                (DWORD_PTR) codeHeaderData.ColdRegionStart,
-                ((DWORD_PTR)codeHeaderData.ColdRegionStart) + codeHeaderData.ColdRegionSize,
-                dwStartAddr,
-                ((DWORD_PTR) MethodDescData.GCStressCodeCopy) + codeHeaderData.HotRegionSize,                
-                fWithGCInfo ? &g_gcEncodingInfo : NULL,
-                pInfo,
-                bSuppressLines,
-                bDisplayOffsets
-                );
-
-    }
+        map.reset(new NOTHROW CLRDATA_IL_ADDRESS_MAP[mapCount]);
+        if (map.get() == NULL)
+        {
+            ReportOOM();
+            return E_OUTOFMEMORY;
+        }
 
-    if (pInfo)
-    {
-        delete pInfo;
-        pInfo = NULL;
-    }
+        if ((Status = pMethodInst->GetILAddressMap(mapCount, &mapCount, map.get())) != S_OK)
+        {
+            return Status;
+        }
 
-    if (fWithGCInfo)
-    {
-        g_gcEncodingInfo.Deinitialize();
+        if (dumpMap)
+        {
+            for (ULONG32 i = 0; i < mapCount; i++)
+            {
+                // TODO: These information should be interleaved with the disassembly
+                // Decoded IL can be obtained through refactoring DumpIL code.
+                ExtOut("%04x %p %p\n", map[i].ilOffset, map[i].startAddress, map[i].endAddress);
+            }
+        }
     }
-    
-    return Status;
+    return S_OK;
 }
 
 /**********************************************************************\
index 054d5b9500d1ed0b23580cea4e857841c4d4758a..2ff025788c562e5eb58fb1a911183cdab1186472 100644 (file)
@@ -21,6 +21,7 @@ inline void RestoreSOToleranceState() {}
 #include <palclr.h>
 #include <metahost.h>
 #include <new>
+#include <functional>
 
 #if !defined(FEATURE_PAL)
 #include <dia2.h>
@@ -1547,10 +1548,12 @@ UINT GetMaxGeneration();
 UINT GetGcHeapCount();
 BOOL GetGcStructuresValid();
 
+void DisassembleToken(IMetaDataImport* i, DWORD token);
 ULONG GetILSize(DWORD_PTR ilAddr); // REturns 0 if error occurs
 HRESULT DecodeILFromAddress(IMetaDataImport *pImport, TADDR ilAddr);
 void DecodeIL(IMetaDataImport *pImport, BYTE *buffer, ULONG bufSize);
 void DecodeDynamicIL(BYTE *data, ULONG Size, DacpObjectData& tokenArray);
+ULONG DisplayILOperation(const UINT indentCount, BYTE* pBuffer, ULONG position, std::function<void(DWORD)>& func);
 
 HRESULT GetRuntimeModuleInfo(PULONG moduleIndex, PULONG64 moduleBase);
 EEFLAVOR GetEEFlavor ();
@@ -3090,6 +3093,5 @@ public:
 private:
     HRESULT PrintCurrentInternalFrame();
 };
-
 #include "sigparser.h"
 #endif // __util_h__