Add missing Arm64 specific diagnostic code (dotnet/coreclr#25695)
authorSteve MacLean <Steve.MacLean@microsoft.com>
Tue, 16 Jul 2019 14:06:52 +0000 (10:06 -0400)
committerGitHub <noreply@github.com>
Tue, 16 Jul 2019 14:06:52 +0000 (10:06 -0400)
* Arm64 ICorDebugRegisterSet float support
* Arm64 ICorDebugRegisterSet2 implementation
* Add arm64 VLT_REG_FP case
* Arm64 add funceval GetRegister SetRegister support

Commit migrated from https://github.com/dotnet/coreclr/commit/f5b1b889a0480eecf7068db4a17e8dd35a7ed878

src/coreclr/src/debug/di/arm64/cordbregisterset.cpp
src/coreclr/src/debug/di/rsthread.cpp
src/coreclr/src/debug/ee/funceval.cpp
src/coreclr/src/vm/arm64/cgencpu.h

index eab5ba4..7921bcf 100644 (file)
@@ -47,7 +47,38 @@ HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG64* pAvailable)
                 | SETBITULONG64(REGISTER_ARM64_X27)
                 | SETBITULONG64(REGISTER_ARM64_X28)
                 | SETBITULONG64(REGISTER_ARM64_FP)
-                | SETBITULONG64(REGISTER_ARM64_LR);
+                | SETBITULONG64(REGISTER_ARM64_LR)
+                | SETBITULONG64(REGISTER_ARM64_V0)
+                | SETBITULONG64(REGISTER_ARM64_V1)
+                | SETBITULONG64(REGISTER_ARM64_V2)
+                | SETBITULONG64(REGISTER_ARM64_V3)
+                | SETBITULONG64(REGISTER_ARM64_V4)
+                | SETBITULONG64(REGISTER_ARM64_V5)
+                | SETBITULONG64(REGISTER_ARM64_V6)
+                | SETBITULONG64(REGISTER_ARM64_V7)
+                | SETBITULONG64(REGISTER_ARM64_V8)
+                | SETBITULONG64(REGISTER_ARM64_V9)
+                | SETBITULONG64(REGISTER_ARM64_V10)
+                | SETBITULONG64(REGISTER_ARM64_V11)
+                | SETBITULONG64(REGISTER_ARM64_V12)
+                | SETBITULONG64(REGISTER_ARM64_V13)
+                | SETBITULONG64(REGISTER_ARM64_V14)
+                | SETBITULONG64(REGISTER_ARM64_V15)
+                | SETBITULONG64(REGISTER_ARM64_V16)
+                | SETBITULONG64(REGISTER_ARM64_V17)
+                | SETBITULONG64(REGISTER_ARM64_V18)
+                | SETBITULONG64(REGISTER_ARM64_V19)
+                | SETBITULONG64(REGISTER_ARM64_V20)
+                | SETBITULONG64(REGISTER_ARM64_V21)
+                | SETBITULONG64(REGISTER_ARM64_V22)
+                | SETBITULONG64(REGISTER_ARM64_V23)
+                | SETBITULONG64(REGISTER_ARM64_V24)
+                | SETBITULONG64(REGISTER_ARM64_V25)
+                | SETBITULONG64(REGISTER_ARM64_V26)
+                | SETBITULONG64(REGISTER_ARM64_V27)
+                | SETBITULONG64(REGISTER_ARM64_V28)
+                | SETBITULONG64(REGISTER_ARM64_V29)
+                | SETBITULONG64(REGISTER_ARM64_V30);
 
     return S_OK;
 }
@@ -63,20 +94,43 @@ HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount,
 
     VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true);
     
-    // @ARM64TODO: floating point support
-
     for (int i = REGISTER_ARM64_PC;
-         i <= REGISTER_ARM64_LR && iRegister < regCount;
+         i <= REGISTER_ARM64_V30 && iRegister < regCount;
          i++)
     {
         if (mask &  SETBITULONG64(i))
         {
+            _ASSERTE (iRegister < regCount);
+
             if ((i >= REGISTER_ARM64_X0) && (i <= REGISTER_ARM64_X28))
             {
                 regBuffer[iRegister++] = m_rd->X[i - REGISTER_ARM64_X0];
                 continue;
             }
 
+            if ((i >= REGISTER_ARM64_V0) && (i <= REGISTER_ARM64_V30))
+            {
+                if (!m_thread->m_fFloatStateValid)
+                {
+                    HRESULT     hr = S_OK;
+                    EX_TRY
+                    {
+                        m_thread->LoadFloatState();
+                    }
+                    EX_CATCH_HRESULT(hr);
+
+                    if ( !SUCCEEDED(hr) )
+                    {
+                        return hr;
+                    }
+                    LOG( ( LF_CORDB, LL_INFO1000, "CRS::GR: Loaded float state\n" ) );
+                }
+
+                regBuffer[iRegister++] = *(CORDB_REGISTER*)
+                                          &(m_thread->m_floatValues[(i - REGISTER_ARM64_V0)]);
+                continue;
+            }
+
             switch (i)
             {
             case REGISTER_ARM64_PC: 
@@ -104,8 +158,19 @@ HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG32 regCount,
     FAIL_IF_NEUTERED(this);
     VALIDATE_POINTER_TO_OBJECT_ARRAY(pAvailable, CORDB_REGISTER, regCount, true, true);
     
-    // Defer to adapter for v1.0 interface
-    return GetRegistersAvailableAdapter(regCount, pAvailable);
+    for (int i = 0 ; i < (int)regCount ; ++i)
+    {
+        if (i * 8 <= REGISTER_ARM64_V31)
+        {
+            pAvailable[i] = (i * 8 == REGISTER_ARM64_V31) ? BYTE(0x1) : BYTE(0xff);
+        }
+        else
+        {
+            pAvailable[i] = 0;
+        }
+    }
+
+    return S_OK;
 }
 
 
@@ -115,8 +180,65 @@ HRESULT CordbRegisterSet::GetRegisters(ULONG32 maskCount, BYTE mask[],
     FAIL_IF_NEUTERED(this);
     VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true);
 
-    // Defer to adapter for v1.0 interface
-    return GetRegistersAdapter(maskCount, mask, regCount, regBuffer);
+    UINT iRegister = 0;
+
+    for (int m = 0 ; m < (int)maskCount ; ++m)
+    {
+        for (int bit = 0 ; bit < 8 ; ++bit)
+        {
+            if (mask[m] & SETBITULONG64(bit))
+            {
+                _ASSERTE (iRegister < regCount);
+
+                int i = m * 8 + bit;
+
+                if ((i >= REGISTER_ARM64_X0) && (i <= REGISTER_ARM64_X28))
+                {
+                    regBuffer[iRegister++] = m_rd->X[i - REGISTER_ARM64_X0];
+                    continue;
+                }
+
+                if ((i >= REGISTER_ARM64_V0) && (i <= REGISTER_ARM64_V31))
+                {
+                    if (!m_thread->m_fFloatStateValid)
+                    {
+                        HRESULT     hr = S_OK;
+                        EX_TRY
+                        {
+                            m_thread->LoadFloatState();
+                        }
+                        EX_CATCH_HRESULT(hr);
+
+                        if ( !SUCCEEDED(hr) )
+                        {
+                            return hr;
+                        }
+                        LOG( ( LF_CORDB, LL_INFO1000, "CRS::GR: Loaded float state\n" ) );
+                    }
+
+                    regBuffer[iRegister++] = *(CORDB_REGISTER*)
+                                              &(m_thread->m_floatValues[(i - REGISTER_ARM64_V0)]);
+                    continue;
+                }
+
+                switch (i)
+                {
+                case REGISTER_ARM64_PC:
+                    regBuffer[iRegister++] = m_rd->PC; break;
+                case REGISTER_ARM64_SP:
+                    regBuffer[iRegister++] = m_rd->SP; break;
+                case REGISTER_ARM64_FP:
+                    regBuffer[iRegister++] = m_rd->FP; break;
+                case REGISTER_ARM64_LR:
+                    regBuffer[iRegister++] = m_rd->LR; break;
+                default:
+                    _ASSERTE(false); break;
+                }
+            }
+        }
+    }
+
+    return S_OK;
 }
 
 
index a9113a4..6ddaaf8 100644 (file)
@@ -8386,10 +8386,14 @@ HRESULT CordbJITILFrame::GetNativeVariable(CordbType *type,
     case ICorDebugInfo::VLT_REG_FP:
 #if defined(DBG_TARGET_ARM) // @ARMTODO
         hr = E_NOTIMPL;
-#else  // DBG_TARGET_ARM @ARMTODO
+#elif defined(DBG_TARGET_AMD64)
         hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg + REGISTER_AMD64_XMM0,
                                                        type, ppValue);
-
+#elif defined(DBG_TARGET_ARM64)
+        hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg + REGISTER_ARM64_V0,
+                                                       type, ppValue);
+#else
+#error Platform not implemented
 #endif  // DBG_TARGET_ARM @ARMTODO
         break;
 #endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
index 8c6ed88..47f5a28 100644 (file)
@@ -388,7 +388,81 @@ static SIZE_T GetRegisterValue(DebuggerEval *pDE, CorDebugRegister reg, void *re
             ret = FPSpillToR8(&(pDE->m_context.Xmm0) + (reg - REGISTER_AMD64_XMM0));
             break;
 
-#endif // !_TARGET_X86_ && !_TARGET_AMD64_
+#elif defined(_TARGET_ARM64_)
+        // fall through
+        case REGISTER_ARM64_X0:
+        case REGISTER_ARM64_X1:
+        case REGISTER_ARM64_X2:
+        case REGISTER_ARM64_X3:
+        case REGISTER_ARM64_X4:
+        case REGISTER_ARM64_X5:
+        case REGISTER_ARM64_X6:
+        case REGISTER_ARM64_X7:
+        case REGISTER_ARM64_X8:
+        case REGISTER_ARM64_X9:
+        case REGISTER_ARM64_X10:
+        case REGISTER_ARM64_X11:
+        case REGISTER_ARM64_X12:
+        case REGISTER_ARM64_X13:
+        case REGISTER_ARM64_X14:
+        case REGISTER_ARM64_X15:
+        case REGISTER_ARM64_X16:
+        case REGISTER_ARM64_X17:
+        case REGISTER_ARM64_X18:
+        case REGISTER_ARM64_X19:
+        case REGISTER_ARM64_X20:
+        case REGISTER_ARM64_X21:
+        case REGISTER_ARM64_X22:
+        case REGISTER_ARM64_X23:
+        case REGISTER_ARM64_X24:
+        case REGISTER_ARM64_X25:
+        case REGISTER_ARM64_X26:
+        case REGISTER_ARM64_X27:
+        case REGISTER_ARM64_X28:
+            ret = pDE->m_context.X[reg - REGISTER_ARM64_X0];
+            break;
+
+        case REGISTER_ARM64_LR:
+            ret = pDE->m_context.Lr;
+            break;
+
+
+        case REGISTER_ARM64_V0:
+        case REGISTER_ARM64_V1:
+        case REGISTER_ARM64_V2:
+        case REGISTER_ARM64_V3:
+        case REGISTER_ARM64_V4:
+        case REGISTER_ARM64_V5:
+        case REGISTER_ARM64_V6:
+        case REGISTER_ARM64_V7:
+        case REGISTER_ARM64_V8:
+        case REGISTER_ARM64_V9:
+        case REGISTER_ARM64_V10:
+        case REGISTER_ARM64_V11:
+        case REGISTER_ARM64_V12:
+        case REGISTER_ARM64_V13:
+        case REGISTER_ARM64_V14:
+        case REGISTER_ARM64_V15:
+        case REGISTER_ARM64_V16:
+        case REGISTER_ARM64_V17:
+        case REGISTER_ARM64_V18:
+        case REGISTER_ARM64_V19:
+        case REGISTER_ARM64_V20:
+        case REGISTER_ARM64_V21:
+        case REGISTER_ARM64_V22:
+        case REGISTER_ARM64_V23:
+        case REGISTER_ARM64_V24:
+        case REGISTER_ARM64_V25:
+        case REGISTER_ARM64_V26:
+        case REGISTER_ARM64_V27:
+        case REGISTER_ARM64_V28:
+        case REGISTER_ARM64_V29:
+        case REGISTER_ARM64_V30:
+        case REGISTER_ARM64_V31:
+            ret = FPSpillToR8(&pDE->m_context.V[reg - REGISTER_ARM64_V0]);
+            break;
+
+#endif // !_TARGET_X86_ && !_TARGET_AMD64_ && !_TARGET_ARM64_
         default:
             _ASSERT(!"Invalid register number!");
 
@@ -530,7 +604,81 @@ static void SetRegisterValue(DebuggerEval *pDE, CorDebugRegister reg, void *regA
             R8ToFPSpill(&(pDE->m_context.Xmm0) + (reg - REGISTER_AMD64_XMM0), newValue);
             break;
 
-#endif // !_TARGET_X86_ && !_TARGET_AMD64_
+#elif defined(_TARGET_ARM64_)
+        // fall through
+        case REGISTER_ARM64_X0:
+        case REGISTER_ARM64_X1:
+        case REGISTER_ARM64_X2:
+        case REGISTER_ARM64_X3:
+        case REGISTER_ARM64_X4:
+        case REGISTER_ARM64_X5:
+        case REGISTER_ARM64_X6:
+        case REGISTER_ARM64_X7:
+        case REGISTER_ARM64_X8:
+        case REGISTER_ARM64_X9:
+        case REGISTER_ARM64_X10:
+        case REGISTER_ARM64_X11:
+        case REGISTER_ARM64_X12:
+        case REGISTER_ARM64_X13:
+        case REGISTER_ARM64_X14:
+        case REGISTER_ARM64_X15:
+        case REGISTER_ARM64_X16:
+        case REGISTER_ARM64_X17:
+        case REGISTER_ARM64_X18:
+        case REGISTER_ARM64_X19:
+        case REGISTER_ARM64_X20:
+        case REGISTER_ARM64_X21:
+        case REGISTER_ARM64_X22:
+        case REGISTER_ARM64_X23:
+        case REGISTER_ARM64_X24:
+        case REGISTER_ARM64_X25:
+        case REGISTER_ARM64_X26:
+        case REGISTER_ARM64_X27:
+        case REGISTER_ARM64_X28:
+            pDE->m_context.X[reg - REGISTER_ARM64_X0] = newValue;
+            break;
+
+        case REGISTER_ARM64_LR:
+            pDE->m_context.Lr = newValue;
+            break;
+
+
+        case REGISTER_ARM64_V0:
+        case REGISTER_ARM64_V1:
+        case REGISTER_ARM64_V2:
+        case REGISTER_ARM64_V3:
+        case REGISTER_ARM64_V4:
+        case REGISTER_ARM64_V5:
+        case REGISTER_ARM64_V6:
+        case REGISTER_ARM64_V7:
+        case REGISTER_ARM64_V8:
+        case REGISTER_ARM64_V9:
+        case REGISTER_ARM64_V10:
+        case REGISTER_ARM64_V11:
+        case REGISTER_ARM64_V12:
+        case REGISTER_ARM64_V13:
+        case REGISTER_ARM64_V14:
+        case REGISTER_ARM64_V15:
+        case REGISTER_ARM64_V16:
+        case REGISTER_ARM64_V17:
+        case REGISTER_ARM64_V18:
+        case REGISTER_ARM64_V19:
+        case REGISTER_ARM64_V20:
+        case REGISTER_ARM64_V21:
+        case REGISTER_ARM64_V22:
+        case REGISTER_ARM64_V23:
+        case REGISTER_ARM64_V24:
+        case REGISTER_ARM64_V25:
+        case REGISTER_ARM64_V26:
+        case REGISTER_ARM64_V27:
+        case REGISTER_ARM64_V28:
+        case REGISTER_ARM64_V29:
+        case REGISTER_ARM64_V30:
+        case REGISTER_ARM64_V31:
+            R8ToFPSpill(&pDE->m_context.V[reg - REGISTER_ARM64_V0], newValue);
+            break;
+
+#endif // !_TARGET_X86_ && !_TARGET_AMD64_ && !_TARGET_ARM64_
         default:
             _ASSERT(!"Invalid register number!");
 
index 997ad7d..9a5fc84 100644 (file)
@@ -71,6 +71,21 @@ extern PCODE GetPreStubEntryPoint();
 //=======================================================================
 #define MAXFIELDMARSHALERSIZE               40
 
+inline
+ARG_SLOT FPSpillToR8(void* pSpillSlot)
+{
+    LIMITED_METHOD_CONTRACT;
+    return *(SIZE_T*)pSpillSlot;
+}
+
+inline
+void     R8ToFPSpill(void* pSpillSlot, SIZE_T  srcDoubleAsSIZE_T)
+{
+    LIMITED_METHOD_CONTRACT;
+    *(SIZE_T*)pSpillSlot = srcDoubleAsSIZE_T;
+    *((SIZE_T*)pSpillSlot + 1) = 0;
+}
+
 //**********************************************************************
 // Parameter size
 //**********************************************************************