VirtualBox

Changeset 86148 in vbox for trunk/src/VBox/Debugger


Ignore:
Timestamp:
Sep 17, 2020 11:22:13 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
140393
Message:

Debugger/DBGCRemoteKd: Some basic register writing code, not fully functional it looks like (register values are not seen even though the write succeeds

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/DBGCRemoteKd.cpp

    r86144 r86148  
    325325    NTCONTEXT64                 Ctx;
    326326} NTKCONTEXT64;
    327 AssertCompileMemberAlignment(NTKCONTEXT64, Ctx, 16);
     327AssertCompileMemberOffset(NTKCONTEXT64, Ctx, 224);
    328328/** Pointer to an amd64 NT context. */
    329329typedef NTKCONTEXT64 *PNTKCONTEXT64;
     
    699699
    700700/**
     701 * Set context manipulate payload.
     702 */
     703typedef struct KDPACKETMANIPULATE_SETCONTEXT
     704{
     705    /** Continue (status?). */
     706    uint32_t                    u32CtxFlags;
     707    /** Blows up the request to the required size. */
     708    uint8_t                     abPad[36];
     709} KDPACKETMANIPULATE_SETCONTEXT;
     710AssertCompileSize(KDPACKETMANIPULATE_SETCONTEXT, 40);
     711/** Pointer to a set context manipulate payload. */
     712typedef KDPACKETMANIPULATE_SETCONTEXT *PKDPACKETMANIPULATE_SETCONTEXT;
     713/** Pointer to a const set context manipulate payload. */
     714typedef const KDPACKETMANIPULATE_SETCONTEXT *PCKDPACKETMANIPULATE_SETCONTEXT;
     715
     716
     717/**
    701718 * Manipulate request packet header (Same for 32bit and 64bit).
    702719 */
     
    739756        /** Continue2. */
    740757        KDPACKETMANIPULATE_CONTINUE2       Continue2;
     758        /** Set context. */
     759        KDPACKETMANIPULATE_SETCONTEXT      SetContext;
    741760        /** Read/Write control space. */
    742761        KDPACKETMANIPULATE_XFERCTRLSPACE64 XferCtrlSpace;
     
    749768    } u;
    750769} KDPACKETMANIPULATE64;
     770AssertCompileSize(KDPACKETMANIPULATE64, 16 + 40);
    751771/** Pointer to a 64bit manipulate state request packet. */
    752772typedef KDPACKETMANIPULATE64 *PKDPACKETMANIPULATE64;
     
    12211241
    12221242
     1243#define KD_REG_INIT(a_pszName, a_enmType, a_ValMember, a_Val) \
     1244    do \
     1245    { \
     1246        aRegsSet[idxReg].pszName = a_pszName; \
     1247        aRegsSet[idxReg].enmType = a_enmType; \
     1248        aRegsSet[idxReg].Val.a_ValMember = a_Val; \
     1249        idxReg++; \
     1250    } while (0)
     1251#define KD_REG_INIT_DTR(a_pszName, a_Base, a_Limit) \
     1252    do \
     1253    { \
     1254        aRegsSet[idxReg].pszName = a_pszName; \
     1255        aRegsSet[idxReg].enmType = DBGFREGVALTYPE_DTR; \
     1256        aRegsSet[idxReg].Val.dtr.u64Base = a_Base; \
     1257        aRegsSet[idxReg].Val.dtr.u32Limit = a_Limit; \
     1258        idxReg++; \
     1259    } while (0)
     1260#define KD_REG_INIT_U16(a_pszName, a_Val) KD_REG_INIT(a_pszName, DBGFREGVALTYPE_U16, u16, a_Val)
     1261#define KD_REG_INIT_U32(a_pszName, a_Val) KD_REG_INIT(a_pszName, DBGFREGVALTYPE_U32, u32, a_Val)
     1262#define KD_REG_INIT_U64(a_pszName, a_Val) KD_REG_INIT(a_pszName, DBGFREGVALTYPE_U64, u64, a_Val)
     1263
     1264
     1265/**
     1266 * Writes the indicated values from the given context structure to the guests register set.
     1267 *
     1268 * @returns VBox status code.
     1269 * @param   pThis               The KD context.
     1270 * @param   idCpu               The CPU to query the context for.
     1271 * @param   pNtCtx              The NT context structure to set.
     1272 * @param   fCtxFlags           Combination of NTCONTEXT_F_XXX determining what to set.
     1273 */
     1274static int dbgcKdCtxSetNtCtx64(PKDCTX pThis, VMCPUID idCpu, PCNTCONTEXT64 pNtCtx, uint32_t fCtxFlags)
     1275{
     1276    uint32_t idxReg = 0;
     1277    DBGFREGENTRYNM aRegsSet[64]; /** @todo Verify that this is enough when fully implemented. */
     1278
     1279    KD_REG_INIT_U32("mxcsr", pNtCtx->u32RegMxCsr);
     1280
     1281    if (fCtxFlags & NTCONTEXT_F_CONTROL)
     1282    {
     1283#if 0 /** @todo CPUM returns VERR_NOT_IMPLEMENTED */
     1284        KD_REG_INIT_U16("cs", pNtCtx->u16SegCs);
     1285        KD_REG_INIT_U16("ss", pNtCtx->u16SegSs);
     1286#endif
     1287        KD_REG_INIT_U64("rip", pNtCtx->u64RegRip);
     1288        KD_REG_INIT_U64("rsp", pNtCtx->u64RegRsp);
     1289        KD_REG_INIT_U64("rbp", pNtCtx->u64RegRbp);
     1290        KD_REG_INIT_U32("rflags", pNtCtx->u32RegEflags);
     1291    }
     1292
     1293    if (fCtxFlags & NTCONTEXT_F_INTEGER)
     1294    {
     1295        KD_REG_INIT_U64("rax", pNtCtx->u64RegRax);
     1296        KD_REG_INIT_U64("rcx", pNtCtx->u64RegRcx);
     1297        KD_REG_INIT_U64("rdx", pNtCtx->u64RegRdx);
     1298        KD_REG_INIT_U64("rbx", pNtCtx->u64RegRbx);
     1299        KD_REG_INIT_U64("rsi", pNtCtx->u64RegRsi);
     1300        KD_REG_INIT_U64("rdi", pNtCtx->u64RegRdi);
     1301        KD_REG_INIT_U64("r8", pNtCtx->u64RegR8);
     1302        KD_REG_INIT_U64("r9", pNtCtx->u64RegR9);
     1303        KD_REG_INIT_U64("r10", pNtCtx->u64RegR10);
     1304        KD_REG_INIT_U64("r11", pNtCtx->u64RegR11);
     1305        KD_REG_INIT_U64("r12", pNtCtx->u64RegR12);
     1306        KD_REG_INIT_U64("r13", pNtCtx->u64RegR13);
     1307        KD_REG_INIT_U64("r14", pNtCtx->u64RegR14);
     1308        KD_REG_INIT_U64("r15", pNtCtx->u64RegR15);
     1309    }
     1310
     1311    if (fCtxFlags & NTCONTEXT_F_SEGMENTS)
     1312    {
     1313#if 0 /** @todo CPUM returns VERR_NOT_IMPLEMENTED */
     1314        KD_REG_INIT_U16("ds", pNtCtx->u16SegDs);
     1315        KD_REG_INIT_U16("es", pNtCtx->u16SegEs);
     1316        KD_REG_INIT_U16("fs", pNtCtx->u16SegFs);
     1317        KD_REG_INIT_U16("gs", pNtCtx->u16SegGs);
     1318#endif
     1319    }
     1320
     1321    if (fCtxFlags & NTCONTEXT_F_FLOATING_POINT)
     1322    {
     1323        /** @todo. */
     1324    }
     1325
     1326    if (fCtxFlags & NTCONTEXT_F_DEBUG)
     1327    {
     1328        /** @todo. */
     1329    }
     1330
     1331    return DBGFR3RegNmSetBatch(pThis->Dbgc.pUVM, idCpu, &aRegsSet[0], idxReg);
     1332}
     1333
     1334
    12231335/**
    12241336 * Fills in the given 64bit NT kernel context structure with the requested values.
     
    12931405
    12941406/**
     1407 * Fills in the given 64bit NT kernel context structure with the requested values.
     1408 *
     1409 * @returns VBox status code.
     1410 * @param   pThis               The KD context.
     1411 * @param   idCpu               The CPU to query the context for.
     1412 * @param   pKNtCtx             The NT context structure to fill in.
     1413 * @param   cbSet               How many bytes of the context are valid.
     1414 */
     1415static int dbgcKdCtxSetNtKCtx64(PKDCTX pThis, VMCPUID idCpu, PCNTKCONTEXT64 pKNtCtx, size_t cbSet)
     1416{
     1417    AssertReturn(cbSet >= RT_UOFFSETOF(NTKCONTEXT64, Ctx), VERR_INVALID_PARAMETER);
     1418
     1419    uint32_t idxReg = 0;
     1420    DBGFREGENTRYNM aRegsSet[64]; /** @todo Verify that this is enough when fully implemented. */
     1421
     1422    KD_REG_INIT_U64("cr0", pKNtCtx->u64RegCr0);
     1423    KD_REG_INIT_U64("cr2", pKNtCtx->u64RegCr2);
     1424    KD_REG_INIT_U64("cr3", pKNtCtx->u64RegCr3);
     1425    KD_REG_INIT_U64("cr4", pKNtCtx->u64RegCr4);
     1426    KD_REG_INIT_U64("cr8", pKNtCtx->u64RegCr8);
     1427    KD_REG_INIT_U64("dr0", pKNtCtx->u64RegDr0);
     1428    KD_REG_INIT_U64("dr1", pKNtCtx->u64RegDr1);
     1429    KD_REG_INIT_U64("dr2", pKNtCtx->u64RegDr2);
     1430    KD_REG_INIT_U64("dr3", pKNtCtx->u64RegDr3);
     1431    KD_REG_INIT_U64("dr6", pKNtCtx->u64RegDr6);
     1432    KD_REG_INIT_U64("dr7", pKNtCtx->u64RegDr7);
     1433
     1434    KD_REG_INIT_DTR("gdtr", pKNtCtx->Gdtr.u64PtrBase, pKNtCtx->Gdtr.u16Limit);
     1435    KD_REG_INIT_DTR("idtr", pKNtCtx->Idtr.u64PtrBase, pKNtCtx->Idtr.u16Limit);
     1436
     1437#if 0 /** @todo CPUM returns VERR_NOT_IMPLEMENTED */
     1438    KD_REG_INIT_U16("tr", pKNtCtx->u16RegTr);
     1439    KD_REG_INIT_U16("ldtr", pKNtCtx->u16RegLdtr);
     1440#endif
     1441    KD_REG_INIT_U32("mxcsr", pKNtCtx->u32RegMxCsr);
     1442
     1443    KD_REG_INIT_U64("msr_gs_base", pKNtCtx->u64MsrGsBase);
     1444    KD_REG_INIT_U64("krnl_gs_base", pKNtCtx->u64MsrKernelGsBase);
     1445    KD_REG_INIT_U64("star", pKNtCtx->u64MsrStar);
     1446    KD_REG_INIT_U64("lstar", pKNtCtx->u64MsrLstar);
     1447    KD_REG_INIT_U64("cstar", pKNtCtx->u64MsrCstar);
     1448    KD_REG_INIT_U64("sf_mask", pKNtCtx->u64MsrSfMask);
     1449
     1450    int rc = DBGFR3RegNmSetBatch(pThis->Dbgc.pUVM, idCpu, &aRegsSet[0], idxReg);
     1451    if (   RT_SUCCESS(rc)
     1452        && cbSet > RT_UOFFSETOF(NTKCONTEXT64, Ctx)) /** @todo Probably wrong. */
     1453        rc = dbgcKdCtxSetNtCtx64(pThis, idCpu, &pKNtCtx->Ctx, pKNtCtx->Ctx.fContext);
     1454
     1455    return rc;
     1456}
     1457
     1458#undef KD_REG_INIT_64
     1459#undef KD_REG_INIT_32
     1460#undef KD_REG_INIT_16
     1461#undef KD_REG_INIT_DTR
     1462#undef KD_REG_INIT
     1463
     1464
     1465/**
    12951466 * Validates the given KD packet header.
    12961467 *
     
    17671938
    17681939/**
    1769  * Processes a read virtual memory 64 request.
     1940 * Processes a read memory 64 request.
    17701941 *
    17711942 * @returns VBox status code.
     
    18191990
    18201991/**
     1992 * Processes a write memory 64 request.
     1993 *
     1994 * @returns VBox status code.
     1995 * @param   pThis               The KD context.
     1996 * @param   pPktManip           The manipulate packet request.
     1997 */
     1998static int dbgcKdCtxPktManipulate64WriteMem(PKDCTX pThis, PCKDPACKETMANIPULATE64 pPktManip)
     1999{
     2000    KDPACKETMANIPULATEHDR RespHdr;
     2001    KDPACKETMANIPULATE_XFERMEM64 XferMem64;
     2002    RT_ZERO(RespHdr); RT_ZERO(XferMem64);
     2003
     2004    DBGFADDRESS AddrWrite;
     2005    const void *pv = &pThis->abBody[sizeof(*pPktManip)]; /* Data comes directly after the manipulate state body. */
     2006    uint32_t cbWrite = RT_MIN(sizeof(pThis->abBody) - sizeof(*pPktManip), pPktManip->u.XferMem.cbXferReq);
     2007    if (pPktManip->Hdr.idReq == KD_PACKET_MANIPULATE_REQ_WRITE_VIRT_MEM)
     2008        DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrWrite, pPktManip->u.XferMem.u64PtrTarget);
     2009    else
     2010        DBGFR3AddrFromPhys(pThis->Dbgc.pUVM, &AddrWrite, pPktManip->u.XferMem.u64PtrTarget);
     2011
     2012    RTSGSEG aRespSegs[2];
     2013    uint32_t cSegs = 2;
     2014    RespHdr.idReq       = pPktManip->Hdr.idReq;
     2015    RespHdr.u16CpuLvl   = pPktManip->Hdr.u16CpuLvl;
     2016    RespHdr.idCpu       = pPktManip->Hdr.idCpu;
     2017    RespHdr.u32NtStatus = NTSTATUS_SUCCESS;
     2018
     2019    XferMem64.u64PtrTarget = pPktManip->u.XferMem.u64PtrTarget;
     2020    XferMem64.cbXferReq    = pPktManip->u.XferMem.cbXferReq;
     2021    XferMem64.cbXfered     = (uint32_t)cbWrite;
     2022
     2023    aRespSegs[0].pvSeg = &RespHdr;
     2024    aRespSegs[0].cbSeg = sizeof(RespHdr);
     2025    aRespSegs[1].pvSeg = &XferMem64;
     2026    aRespSegs[1].cbSeg = sizeof(XferMem64);
     2027
     2028    int rc = DBGFR3MemWrite(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, &AddrWrite, pv, cbWrite);
     2029    if (RT_FAILURE(rc))
     2030        RespHdr.u32NtStatus = NTSTATUS_UNSUCCESSFUL; /** @todo Convert to an appropriate NT status code. */
     2031
     2032    return dbgcKdCtxPktSendSg(pThis, KD_PACKET_HDR_SIGNATURE_DATA, KD_PACKET_HDR_SUB_TYPE_STATE_MANIPULATE,
     2033                              &aRespSegs[0], cSegs, true /*fAck*/);
     2034}
     2035
     2036
     2037/**
    18212038 * Processes a continue request.
    18222039 *
     
    18612078
    18622079    return rc;
     2080}
     2081
     2082
     2083/**
     2084 * Processes a set context request.
     2085 *
     2086 * @returns VBox status code.
     2087 * @param   pThis               The KD context.
     2088 * @param   pPktManip           The manipulate packet request.
     2089 */
     2090static int dbgcKdCtxPktManipulate64SetContext(PKDCTX pThis, PCKDPACKETMANIPULATE64 pPktManip)
     2091{
     2092    KDPACKETMANIPULATEHDR RespHdr;
     2093    KDPACKETMANIPULATE_SETCONTEXT SetContext;
     2094    RT_ZERO(RespHdr); RT_ZERO(SetContext);
     2095
     2096    PCNTCONTEXT64 pNtCtx = (PCNTCONTEXT64)&pThis->abBody[sizeof(*pPktManip)]; /* Data comes directly after the manipulate state body. */
     2097
     2098    RTSGSEG aRespSegs[2];
     2099    uint32_t cSegs = 2;
     2100    RespHdr.idReq       = pPktManip->Hdr.idReq;
     2101    RespHdr.u16CpuLvl   = pPktManip->Hdr.u16CpuLvl;
     2102    RespHdr.idCpu       = pPktManip->Hdr.idCpu;
     2103    RespHdr.u32NtStatus = NTSTATUS_SUCCESS;
     2104
     2105    SetContext.u32CtxFlags = pPktManip->u.SetContext.u32CtxFlags;
     2106
     2107    aRespSegs[0].pvSeg = &RespHdr;
     2108    aRespSegs[0].cbSeg = sizeof(RespHdr);
     2109    aRespSegs[1].pvSeg = &SetContext;
     2110    aRespSegs[1].cbSeg = sizeof(SetContext);
     2111
     2112    int rc = dbgcKdCtxSetNtCtx64(pThis, pPktManip->Hdr.idCpu, pNtCtx, SetContext.u32CtxFlags);
     2113    if (RT_FAILURE(rc))
     2114        RespHdr.u32NtStatus = NTSTATUS_UNSUCCESSFUL; /** @todo Convert to an appropriate NT status code. */
     2115
     2116    return dbgcKdCtxPktSendSg(pThis, KD_PACKET_HDR_SIGNATURE_DATA, KD_PACKET_HDR_SUB_TYPE_STATE_MANIPULATE,
     2117                              &aRespSegs[0], cSegs, true /*fAck*/);
    18632118}
    18642119
     
    19732228
    19742229/**
     2230 * Processes a write control space 64 request.
     2231 *
     2232 * @returns VBox status code.
     2233 * @param   pThis               The KD context.
     2234 * @param   pPktManip           The manipulate packet request.
     2235 */
     2236static int dbgcKdCtxPktManipulate64WriteCtrlSpace(PKDCTX pThis, PCKDPACKETMANIPULATE64 pPktManip)
     2237{
     2238    KDPACKETMANIPULATEHDR RespHdr;
     2239    KDPACKETMANIPULATE_XFERCTRLSPACE64 XferCtrlSpace64;
     2240    uint32_t cbData = 0;
     2241    RT_ZERO(RespHdr); RT_ZERO(XferCtrlSpace64);
     2242
     2243    RTSGSEG aRespSegs[2];
     2244    RespHdr.idReq       = KD_PACKET_MANIPULATE_REQ_WRITE_CTRL_SPACE;
     2245    RespHdr.u16CpuLvl   = pPktManip->Hdr.u16CpuLvl;
     2246    RespHdr.idCpu       = pPktManip->Hdr.idCpu;
     2247    RespHdr.u32NtStatus = NTSTATUS_SUCCESS;
     2248
     2249    XferCtrlSpace64.u64IdXfer = pPktManip->u.XferCtrlSpace.u64IdXfer;
     2250    XferCtrlSpace64.cbXferReq = pPktManip->u.XferCtrlSpace.cbXferReq;
     2251
     2252    aRespSegs[0].pvSeg = &RespHdr;
     2253    aRespSegs[0].cbSeg = sizeof(RespHdr);
     2254    aRespSegs[1].pvSeg = &XferCtrlSpace64;
     2255    aRespSegs[1].cbSeg = sizeof(XferCtrlSpace64);
     2256
     2257    int rc = VINF_SUCCESS;
     2258    switch (pPktManip->u.XferCtrlSpace.u64IdXfer)
     2259    {
     2260        case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KCTX:
     2261        {
     2262            PCNTKCONTEXT64 pNtKCtx = (PCNTKCONTEXT64)&pThis->abBody[sizeof(*pPktManip)]; /* Data comes directly after the manipulate state body. */
     2263            rc = dbgcKdCtxSetNtKCtx64(pThis, RespHdr.idCpu, pNtKCtx, XferCtrlSpace64.cbXferReq);
     2264            if (RT_SUCCESS(rc))
     2265                cbData = RT_MIN(XferCtrlSpace64.cbXferReq, sizeof(NTKCONTEXT64));
     2266            break;
     2267        }
     2268        case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KPCR:
     2269        case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KPCRB:
     2270        case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KTHRD:
     2271        default:
     2272            rc = VERR_NOT_SUPPORTED;
     2273            break;
     2274    }
     2275
     2276    if (RT_FAILURE(rc))
     2277        RespHdr.u32NtStatus = NTSTATUS_UNSUCCESSFUL; /** @todo Convert to an appropriate NT status code. */
     2278    else
     2279        XferCtrlSpace64.cbXfered = cbData;
     2280
     2281    return dbgcKdCtxPktSendSg(pThis, KD_PACKET_HDR_SIGNATURE_DATA, KD_PACKET_HDR_SUB_TYPE_STATE_MANIPULATE,
     2282                              &aRespSegs[0], RT_ELEMENTS(aRespSegs), true /*fAck*/);
     2283}
     2284
     2285
     2286/**
    19752287 * Processes a restore breakpoint 64 request.
    19762288 *
     
    21172429            break;
    21182430        }
     2431        case KD_PACKET_MANIPULATE_REQ_WRITE_VIRT_MEM:
     2432        case KD_PACKET_MANIPULATE_REQ_WRITE_PHYS_MEM:
     2433        {
     2434            rc = dbgcKdCtxPktManipulate64WriteMem(pThis, pPktManip);
     2435            break;
     2436        }
    21192437        case KD_PACKET_MANIPULATE_REQ_CONTINUE:
    21202438        {
     
    21272445            break;
    21282446        }
     2447        case KD_PACKET_MANIPULATE_REQ_SET_CONTEXT:
     2448        {
     2449            rc = dbgcKdCtxPktManipulate64SetContext(pThis, pPktManip);
     2450            break;
     2451        }
    21292452        case KD_PACKET_MANIPULATE_REQ_READ_CTRL_SPACE:
    21302453        {
    21312454            rc = dbgcKdCtxPktManipulate64ReadCtrlSpace(pThis, pPktManip);
     2455            break;
     2456        }
     2457        case KD_PACKET_MANIPULATE_REQ_WRITE_CTRL_SPACE:
     2458        {
     2459            rc = dbgcKdCtxPktManipulate64WriteCtrlSpace(pThis, pPktManip);
    21322460            break;
    21332461        }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette