[RISC-V] Implement SOS related Debugger API code. (#94454)
authorMikhail Kurinnoi <m.kurinnoi@samsung.com>
Thu, 9 Nov 2023 17:20:58 +0000 (20:20 +0300)
committerGleb Balykov <g.balykov@samsung.com>
Fri, 15 Dec 2023 12:28:32 +0000 (15:28 +0300)
* [RISC-V] Implement SOS related Debugger API code.

* [RISC-V] Fix R0 copy.

* [RISC-V] Remove R0 from DebuggerREGDISPLAY.

src/coreclr/debug/di/rsthread.cpp
src/coreclr/debug/inc/dbgipcevents.h
src/coreclr/debug/inc/riscv64/primitives.h
src/coreclr/debug/shared/riscv64/primitives.cpp
src/coreclr/inc/cordebug.idl
src/coreclr/inc/gcinfodecoder.h
src/coreclr/inc/regdisp.h
src/coreclr/pal/prebuilt/inc/cordebug.h

index 4cc3872..385addc 100644 (file)
@@ -6357,6 +6357,126 @@ UINT_PTR * CordbNativeFrame::GetAddressOfRegister(CorDebugRegister regNum) const
     case REGISTER_ARM64_PC:
         ret = (UINT_PTR*)&m_rd.PC;
         break;
+#elif defined(TARGET_RISCV64)
+    case REGISTER_RISCV64_PC:
+        ret = (UINT_PTR*)&m_rd.PC;
+        break;
+
+    case REGISTER_RISCV64_RA:
+        ret = (UINT_PTR*)&m_rd.RA;
+        break;
+
+    case REGISTER_RISCV64_GP:
+        ret = (UINT_PTR*)&m_rd.GP;
+        break;
+
+    case REGISTER_RISCV64_TP:
+        ret = (UINT_PTR*)&m_rd.TP;
+        break;
+
+    case REGISTER_RISCV64_T0:
+        ret = (UINT_PTR*)&m_rd.T0;
+        break;
+
+    case REGISTER_RISCV64_T1:
+        ret = (UINT_PTR*)&m_rd.T1;
+        break;
+
+    case REGISTER_RISCV64_T2:
+        ret = (UINT_PTR*)&m_rd.T2;
+        break;
+
+    case REGISTER_RISCV64_S1:
+        ret = (UINT_PTR*)&m_rd.S1;
+        break;
+
+    case REGISTER_RISCV64_A0:
+        ret = (UINT_PTR*)&m_rd.A0;
+        break;
+
+    case REGISTER_RISCV64_A1:
+        ret = (UINT_PTR*)&m_rd.A1;
+        break;
+
+    case REGISTER_RISCV64_A2:
+        ret = (UINT_PTR*)&m_rd.A2;
+        break;
+
+    case REGISTER_RISCV64_A3:
+        ret = (UINT_PTR*)&m_rd.A3;
+        break;
+
+    case REGISTER_RISCV64_A4:
+        ret = (UINT_PTR*)&m_rd.A4;
+        break;
+
+    case REGISTER_RISCV64_A5:
+        ret = (UINT_PTR*)&m_rd.A5;
+        break;
+
+    case REGISTER_RISCV64_A6:
+        ret = (UINT_PTR*)&m_rd.A6;
+        break;
+
+    case REGISTER_RISCV64_A7:
+        ret = (UINT_PTR*)&m_rd.A7;
+        break;
+
+    case REGISTER_RISCV64_S2:
+        ret = (UINT_PTR*)&m_rd.S2;
+        break;
+
+    case REGISTER_RISCV64_S3:
+        ret = (UINT_PTR*)&m_rd.S3;
+        break;
+
+    case REGISTER_RISCV64_S4:
+        ret = (UINT_PTR*)&m_rd.S4;
+        break;
+
+    case REGISTER_RISCV64_S5:
+        ret = (UINT_PTR*)&m_rd.S5;
+        break;
+
+    case REGISTER_RISCV64_S6:
+        ret = (UINT_PTR*)&m_rd.S6;
+        break;
+
+    case REGISTER_RISCV64_S7:
+        ret = (UINT_PTR*)&m_rd.S7;
+        break;
+
+    case REGISTER_RISCV64_S8:
+        ret = (UINT_PTR*)&m_rd.S8;
+        break;
+
+    case REGISTER_RISCV64_S9:
+        ret = (UINT_PTR*)&m_rd.S9;
+        break;
+
+    case REGISTER_RISCV64_S10:
+        ret = (UINT_PTR*)&m_rd.S10;
+        break;
+
+    case REGISTER_RISCV64_S11:
+        ret = (UINT_PTR*)&m_rd.S11;
+        break;
+
+    case REGISTER_RISCV64_T3:
+        ret = (UINT_PTR*)&m_rd.T3;
+        break;
+
+    case REGISTER_RISCV64_T4:
+        ret = (UINT_PTR*)&m_rd.T4;
+        break;
+
+    case REGISTER_RISCV64_T5:
+        ret = (UINT_PTR*)&m_rd.T5;
+        break;
+
+    case REGISTER_RISCV64_T6:
+        ret = (UINT_PTR*)&m_rd.T6;
+        break;
 #endif
 
     default:
index e9643e5..0eb393c 100644 (file)
@@ -1171,6 +1171,40 @@ struct MSLAYOUT DebuggerREGDISPLAY
     SIZE_T  S7;
     SIZE_T  S8;
     SIZE_T  PC;
+#elif defined(TARGET_RISCV64)
+    #define DebuggerIPCE_FloatCount 32
+    SIZE_T  RA;
+    SIZE_T  SP;
+    SIZE_T  GP;
+    SIZE_T  TP;
+    SIZE_T  T0;
+    SIZE_T  T1;
+    SIZE_T  T2;
+    SIZE_T  FP;
+    SIZE_T  S1;
+    SIZE_T  A0;
+    SIZE_T  A1;
+    SIZE_T  A2;
+    SIZE_T  A3;
+    SIZE_T  A4;
+    SIZE_T  A5;
+    SIZE_T  A6;
+    SIZE_T  A7;
+    SIZE_T  S2;
+    SIZE_T  S3;
+    SIZE_T  S4;
+    SIZE_T  S5;
+    SIZE_T  S6;
+    SIZE_T  S7;
+    SIZE_T  S8;
+    SIZE_T  S9;
+    SIZE_T  S10;
+    SIZE_T  S11;
+    SIZE_T  T3;
+    SIZE_T  T4;
+    SIZE_T  T5;
+    SIZE_T  T6;
+    SIZE_T  PC;
 #else
     #define DebuggerIPCE_FloatCount 1
 
index 39c505b..44475ac 100644 (file)
@@ -49,7 +49,7 @@ inline CORDB_ADDRESS GetPatchEndAddr(CORDB_ADDRESS patchAddr)
 
 constexpr CorDebugRegister g_JITToCorDbgReg[] =
 {
-    REGISTER_RISCV64_X0, // TODO-RISCV64-CQ: Add X0 to access DbgReg in correct order
+    (CorDebugRegister)(-1), // X0 is zero register that is not a real register. We need padding here for proper mapping with ICorDebugInfo::RegNum.
     REGISTER_RISCV64_RA,
     REGISTER_RISCV64_SP,
     REGISTER_RISCV64_GP,
@@ -159,7 +159,7 @@ inline PRD_TYPE CORDbgGetInstruction(UNALIGNED CORDB_ADDRESS_TYPE* address)
 inline CorDebugRegister ConvertRegNumToCorDebugRegister(ICorDebugInfo::RegNum reg)
 {
     LIMITED_METHOD_CONTRACT;
-    _ASSERTE(reg >= 0);
+    _ASSERTE(reg > 0);
     _ASSERTE(static_cast<size_t>(reg) < ARRAY_SIZE(g_JITToCorDbgReg));
     return g_JITToCorDbgReg[reg];
 }
index 112f76f..b351da1 100644 (file)
 //
 void CORDbgCopyThreadContext(DT_CONTEXT* pDst, const DT_CONTEXT* pSrc)
 {
-    _ASSERTE(!"RISCV64:NYI");
+    DWORD dstFlags = pDst->ContextFlags;
+    DWORD srcFlags = pSrc->ContextFlags;
+    LOG((LF_CORDB, LL_INFO1000000,
+         "CP::CTC: pDst=0x%08x dstFlags=0x%x, pSrc=0x%08x srcFlags=0x%x\n",
+         pDst, dstFlags, pSrc, srcFlags));
+
+    if ((dstFlags & srcFlags & DT_CONTEXT_CONTROL) == DT_CONTEXT_CONTROL)
+    {
+        LOG((LF_CORDB, LL_INFO1000000,
+             "CP::CTC: RA: pDst=0x%lx, pSrc=0x%lx, Flags=0x%x\n",
+             pDst->Ra, pSrc->Ra, DT_CONTEXT_CONTROL));
+        pDst->Ra = pSrc->Ra;
+
+        LOG((LF_CORDB, LL_INFO1000000,
+             "CP::CTC: SP: pDst=0x%lx, pSrc=0x%lx, Flags=0x%x\n",
+             pDst->Sp, pSrc->Sp, DT_CONTEXT_CONTROL));
+        pDst->Sp = pSrc->Sp;
+
+        LOG((LF_CORDB, LL_INFO1000000,
+             "CP::CTC: FP: pDst=0x%lx, pSrc=0x%lx, Flags=0x%x\n",
+             pDst->Fp, pSrc->Fp, DT_CONTEXT_CONTROL));
+        pDst->Fp = pSrc->Fp;
+
+        LOG((LF_CORDB, LL_INFO1000000,
+             "CP::CTC: PC: pDst=0x%lx, pSrc=0x%lx, Flags=0x%x\n",
+             pDst->Pc, pSrc->Pc, DT_CONTEXT_CONTROL));
+        pDst->Pc = pSrc->Pc;
+    }
+
+    if ((dstFlags & srcFlags & DT_CONTEXT_INTEGER) == DT_CONTEXT_INTEGER)
+    {
+        CopyContextChunk(&pDst->Gp, &pSrc->Gp, &pDst->Fp,
+                         DT_CONTEXT_INTEGER);
+        CopyContextChunk(&pDst->S1, &pSrc->S1, &pDst->Pc,
+                         DT_CONTEXT_INTEGER);
+        LOG((LF_CORDB, LL_INFO1000000,
+             "CP::CTC: T0: pDst=0x%lx, pSrc=0x%lx, Flags=0x%x\n",
+             pDst->R0, pSrc->R0, DT_CONTEXT_INTEGER));
+        pDst->R0 = pSrc->R0;
+    }
+
+    if ((dstFlags & srcFlags & DT_CONTEXT_FLOATING_POINT) == DT_CONTEXT_FLOATING_POINT)
+    {
+        CopyContextChunk(&pDst->F[0], &pSrc->F[0], &pDst->F[32],
+                         DT_CONTEXT_FLOATING_POINT);
+        pDst->Fcsr = pSrc->Fcsr;
+    }
 }
 
 #if defined(ALLOW_VMPTR_ACCESS) || !defined(RIGHT_SIDE_COMPILE)
 void SetDebuggerREGDISPLAYFromREGDISPLAY(DebuggerREGDISPLAY* pDRD, REGDISPLAY* pRD)
 {
-    _ASSERTE(!"RISCV64:NYI");
+    SUPPORTS_DAC_HOST_ONLY;
+
+    DT_CONTEXT* pContext = reinterpret_cast<DT_CONTEXT*>(pRD->pCurrentContext);
+
+    // We must pay attention to the context flags so that we only use valid portions
+    // of the context.
+    DWORD flags = pContext->ContextFlags;
+    if ((flags & DT_CONTEXT_CONTROL) == DT_CONTEXT_CONTROL)
+    {
+        pDRD->FP = (SIZE_T)CORDbgGetFP(pContext);
+        pDRD->PC = (SIZE_T)pContext->Pc;
+        pDRD->RA = (SIZE_T)pContext->Ra;
+    }
+
+    if ((flags & DT_CONTEXT_INTEGER) == DT_CONTEXT_INTEGER)
+    {
+        memcpy(&pDRD->GP, &pContext->Gp, sizeof(pDRD->GP) * 5);
+        memcpy(&pDRD->S1, &pContext->S1, sizeof(pDRD->S1) * 23);
+    }
+
+    pDRD->SP = pRD->SP;
+
+    LOG( (LF_CORDB, LL_INFO1000, "DT::TASSC:Registers:"
+          "SP = %x",
+          pDRD->SP) );
 }
 #endif // ALLOW_VMPTR_ACCESS || !RIGHT_SIDE_COMPILE
index af3f6eb..2e06651 100644 (file)
@@ -3988,14 +3988,14 @@ interface ICorDebugRegisterSet : IUnknown
         REGISTER_LOONGARCH64_F31,
 
         REGISTER_RISCV64_PC = 0,
-        REGISTER_RISCV64_RA,
         REGISTER_RISCV64_SP,
+        REGISTER_RISCV64_FP,
+        REGISTER_RISCV64_RA,
         REGISTER_RISCV64_GP,
         REGISTER_RISCV64_TP,
         REGISTER_RISCV64_T0,
         REGISTER_RISCV64_T1,
         REGISTER_RISCV64_T2,
-        REGISTER_RISCV64_FP,
         REGISTER_RISCV64_S1,
         REGISTER_RISCV64_A0,
         REGISTER_RISCV64_A1,
@@ -4050,8 +4050,7 @@ interface ICorDebugRegisterSet : IUnknown
         REGISTER_RISCV64_F28,
         REGISTER_RISCV64_F29,
         REGISTER_RISCV64_F30,
-        REGISTER_RISCV64_F31,
-        REGISTER_RISCV64_X0, // TODO-RISCV64-CQ: Add X0 for an use in debug. Need to check.
+        REGISTER_RISCV64_F31
 
         // other architectures here
 
index f65cb58..36e86a3 100644 (file)
@@ -87,6 +87,8 @@ inline TADDR GetSP(T_CONTEXT* context)
     return (TADDR)context->Sp;
 #elif defined(TARGET_LOONGARCH64)
     return (TADDR)context->Sp;
+#elif defined(TARGET_RISCV64)
+    return (TADDR)context->Sp;
 #else
     _ASSERTE(!"nyi for platform");
 #endif
@@ -102,6 +104,8 @@ inline PCODE GetIP(T_CONTEXT* context)
     return (PCODE)context->Pc;
 #elif defined(TARGET_LOONGARCH64)
     return (PCODE)context->Pc;
+#elif defined(TARGET_RISCV64)
+    return (PCODE)context->Pc;
 #else
     _ASSERTE(!"nyi for platform");
 #endif
index c3b4b44..4832791 100644 (file)
@@ -277,7 +277,7 @@ inline TADDR GetRegdisplayStackMark(REGDISPLAY *display)
     _ASSERTE(GetRegdisplaySP(display) == GetSP(display->pCurrentContext));
     return GetRegdisplaySP(display);
 
-#elif defined(TARGET_ARM64)
+#elif defined(TARGET_ARM64) || defined(TARGET_RISCV64)
 
     _ASSERTE(display->IsCallerContextValid);
     return GetSP(display->pCallerContext);
index a9ec5ff..6d74b1a 100644 (file)
@@ -9707,15 +9707,15 @@ enum CorDebugRegister
         REGISTER_LOONGARCH64_F30    = ( REGISTER_LOONGARCH64_F29 + 1 ) ,
         REGISTER_LOONGARCH64_F31    = ( REGISTER_LOONGARCH64_F30 + 1 ) ,
         REGISTER_RISCV64_PC = 0,
-        REGISTER_RISCV64_RA = ( REGISTER_RISCV64_PC + 1 ) ,
-        REGISTER_RISCV64_SP = ( REGISTER_RISCV64_RA + 1 ) ,
-        REGISTER_RISCV64_GP = ( REGISTER_RISCV64_SP + 1 ) ,
+        REGISTER_RISCV64_SP = ( REGISTER_RISCV64_PC + 1 ) ,
+        REGISTER_RISCV64_FP = ( REGISTER_RISCV64_SP + 1 ) ,
+        REGISTER_RISCV64_RA = ( REGISTER_RISCV64_FP + 1 ) ,
+        REGISTER_RISCV64_GP = ( REGISTER_RISCV64_RA + 1 ) ,
         REGISTER_RISCV64_TP = ( REGISTER_RISCV64_GP + 1 ) ,
         REGISTER_RISCV64_T0 = ( REGISTER_RISCV64_TP + 1 ) ,
         REGISTER_RISCV64_T1 = ( REGISTER_RISCV64_T0 + 1 ) ,
         REGISTER_RISCV64_T2 = ( REGISTER_RISCV64_T1 + 1 ) ,
-        REGISTER_RISCV64_FP = ( REGISTER_RISCV64_T2 + 1 ) ,
-        REGISTER_RISCV64_S1 = ( REGISTER_RISCV64_FP + 1 ) ,
+        REGISTER_RISCV64_S1 = ( REGISTER_RISCV64_T2 + 1 ) ,
         REGISTER_RISCV64_A0 = ( REGISTER_RISCV64_S1 + 1 ) ,
         REGISTER_RISCV64_A1 = ( REGISTER_RISCV64_A0 + 1 ) ,
         REGISTER_RISCV64_A2 = ( REGISTER_RISCV64_A1 + 1 ) ,
@@ -9769,8 +9769,7 @@ enum CorDebugRegister
         REGISTER_RISCV64_F28    = ( REGISTER_RISCV64_F27 + 1 ) ,
         REGISTER_RISCV64_F29    = ( REGISTER_RISCV64_F28 + 1 ) ,
         REGISTER_RISCV64_F30    = ( REGISTER_RISCV64_F29 + 1 ) ,
-        REGISTER_RISCV64_F31    = ( REGISTER_RISCV64_F30 + 1 ) ,
-        REGISTER_RISCV64_X0 = ( REGISTER_RISCV64_F31 + 1 ) 
+        REGISTER_RISCV64_F31    = ( REGISTER_RISCV64_F30 + 1 )
     }   CorDebugRegister;