VirtualBox

Changeset 86165 in vbox


Ignore:
Timestamp:
Sep 18, 2020 9:54:18 AM (4 years ago)
Author:
vboxsync
Message:

Debugger/DBGCRemoteKd: Start supporting 32bit guests

File:
1 edited

Legend:

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

    r86160 r86165  
    5959 * From: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kprcb/amd64.htm */
    6060#define KD_KPCR_VERSION_BLOCK_ADDR_OFF              0x34
     61
    6162
    6263/*********************************************************************************************************************************
     
    249250
    250251/**
    251  * [GI]DT descriptor.
     252 * 64bit [GI]DT descriptor.
    252253 */
    253254typedef struct NTKCONTEXTDESC64
     
    261262} NTKCONTEXTDESC64;
    262263AssertCompileSize(NTKCONTEXTDESC64, 2 * 8);
    263 /** Pointer to an amd64 NT context. */
     264/** Pointer to a 64bit [GI]DT descriptor. */
    264265typedef NTKCONTEXTDESC64 *PNTKCONTEXTDESC64;
    265 /** Pointer to a const amd64 NT context. */
     266/** Pointer to a const 64bit [GI]DT descriptor. */
    266267typedef const NTKCONTEXTDESC64 *PCNTKCONTEXTDESC64;
    267268
     
    335336
    336337
     338/**
     339 * 32bit context FPU save area.
     340 */
     341typedef struct NTCONTEXT32_FPU_SAVE_AREA
     342{
     343    uint32_t                    u32CtrlWord;
     344    uint32_t                    u32StatusWord;
     345    uint32_t                    u32TagWord;
     346    uint32_t                    u32ErrorOff;
     347    uint32_t                    u32ErrorSel;
     348    uint32_t                    u32DataOff;
     349    uint32_t                    u32DataSel;
     350    uint8_t                     abRegArea[80];
     351    uint32_t                    u32Cr0Npx;
     352} NTCONTEXT32_FPU_SAVE_AREA;
     353/** Pointer to an 32bit context FPU save area. */
     354typedef NTCONTEXT32_FPU_SAVE_AREA *PNTCONTEXT32_FPU_SAVE_AREA;
     355/** Pointer to a const 32bit context FPU save area. */
     356typedef const NTCONTEXT32_FPU_SAVE_AREA *PCNTCONTEXT32_FPU_SAVE_AREA;
     357
     358
     359/**
     360 * i386 NT context structure.
     361 */
     362typedef struct NTCONTEXT32
     363{
     364    /** Context flags indicating the valid bits, see NTCONTEXT_F_XXX. */
     365    uint32_t                    fContext;
     366    /** DR0 register. */
     367    uint32_t                    u32RegDr0;
     368    /** DR1 register. */
     369    uint32_t                    u32RegDr1;
     370    /** DR2 register. */
     371    uint32_t                    u32RegDr2;
     372    /** DR3 register. */
     373    uint32_t                    u32RegDr3;
     374    /** DR6 register. */
     375    uint32_t                    u32RegDr6;
     376    /** DR7 register. */
     377    uint32_t                    u32RegDr7;
     378    /** Floating point save area. */
     379    NTCONTEXT32_FPU_SAVE_AREA   FloatSave;
     380    /** GS segment. */
     381    uint32_t                    u32SegGs;
     382    /** FS segment. */
     383    uint32_t                    u32SegFs;
     384    /** ES segment. */
     385    uint32_t                    u32SegEs;
     386    /** DS segment. */
     387    uint32_t                    u32SegDs;
     388    /** EDI register. */
     389    uint32_t                    u32RegEdi;
     390    /** ESI register. */
     391    uint32_t                    u32RegEsi;
     392    /** EBX register. */
     393    uint32_t                    u32RegEbx;
     394    /** EDX register. */
     395    uint32_t                    u32RegEdx;
     396    /** ECX register. */
     397    uint32_t                    u32RegEcx;
     398    /** EAX register. */
     399    uint32_t                    u32RegEax;
     400    /** EBP register. */
     401    uint32_t                    u32RegEbp;
     402    /** EIP register. */
     403    uint32_t                    u32RegEip;
     404    /** CS segment. */
     405    uint32_t                    u32SegCs;
     406    /** EFLAGS register. */
     407    uint32_t                    u32RegEflags;
     408    /** ESP register. */
     409    uint32_t                    u32RegEsp;
     410    /** SS segment. */
     411    uint32_t                    u32SegSs;
     412    /** @todo Extended registers */
     413    uint8_t                     abRegsExtended[512];
     414} NTCONTEXT32;
     415AssertCompileSize(NTCONTEXT32, 716);
     416/** Pointer to an i386 NT context. */
     417typedef NTCONTEXT32 *PNTCONTEXT32;
     418/** Pointer to a const i386 NT context. */
     419typedef const NTCONTEXT32 *PCNTCONTEXT32;
     420
     421
     422/**
     423 * 32bit [GI]DT descriptor.
     424 */
     425typedef struct NTKCONTEXTDESC32
     426{
     427    /** Alignment. */
     428    uint16_t                    u16Alignment;
     429    /** Limit. */
     430    uint16_t                    u16Limit;
     431    /** Base address. */
     432    uint32_t                    u32PtrBase;
     433} NTKCONTEXTDESC32;
     434AssertCompileSize(NTKCONTEXTDESC32, 2 * 4);
     435/** Pointer to an 32bit [GI]DT descriptor. */
     436typedef NTKCONTEXTDESC32 *PNTKCONTEXTDESC32;
     437/** Pointer to a const 32bit [GI]DT descriptor. */
     438typedef const NTKCONTEXTDESC32 *PCNTKCONTEXTDESC32;
     439
     440
     441/**
     442 * 32bit Kernel context as queried by KD_PACKET_MANIPULATE_REQ_READ_CTRL_SPACE
     443 */
     444typedef struct NTKCONTEXT32
     445{
     446    /** CR0 register. */
     447    uint32_t                    u32RegCr0;
     448    /** CR2 register. */
     449    uint32_t                    u32RegCr2;
     450    /** CR3 register. */
     451    uint32_t                    u32RegCr3;
     452    /** CR4 register. */
     453    uint32_t                    u32RegCr4;
     454    /** DR0 register. */
     455    uint32_t                    u32RegDr0;
     456    /** DR1 register. */
     457    uint32_t                    u32RegDr1;
     458    /** DR2 register. */
     459    uint32_t                    u32RegDr2;
     460    /** DR3 register. */
     461    uint32_t                    u32RegDr3;
     462    /** DR6 register. */
     463    uint32_t                    u32RegDr6;
     464    /** DR7 register. */
     465    uint32_t                    u32RegDr7;
     466    /** GDTR. */
     467    NTKCONTEXTDESC32            Gdtr;
     468    /** IDTR. */
     469    NTKCONTEXTDESC32            Idtr;
     470    /** TR register. */
     471    uint16_t                    u16RegTr;
     472    /** LDTR register. */
     473    uint16_t                    u16RegLdtr;
     474    /** Padding. */
     475    uint8_t                     abPad[24];
     476} NTKCONTEXT32;
     477AssertCompileSize(NTKCONTEXT32, 84);
     478/** Pointer to an i386 NT context. */
     479typedef NTKCONTEXT32 *PNTKCONTEXT32;
     480/** Pointer to a const i386 NT context. */
     481typedef const NTKCONTEXT32 *PCNTKCONTEXT32;
     482
     483
    337484/** x86 context. */
    338485#define NTCONTEXT_F_X86                             UINT32_C(0x00010000)
     
    9051052    /** Pointer to the OS digger WinNt interface if a matching guest was detected. */
    9061053    PDBGFOSIWINNT               pIfWinNt;
     1054    /** Flag whether the detected guest is 32bit (false if 64bit). */
     1055    bool                        f32Bit;
    9071056} KDCTX;
    9081057/** Pointer to the KD context data. */
     
    9121061/** Pointer to a KD context data pointer. */
    9131062typedef PKDCTX *PPKDCTX;
     1063
     1064
     1065/** Creates a possibly sign extended guest context pointer which is required for 32bit targets. */
     1066#define KD_PTR_CREATE(a_pThis, a_GCPtr) ((a_pThis)->f32Bit && ((a_GCPtr) & RT_BIT_32(31)) ? (a_GCPtr) | UINT64_C(0xffffffff00000000) : (a_GCPtr))
     1067/** Returns the value of a possibly sign extended guest context pointer received for 32bit targets. */
     1068#define KD_PTR_GET(a_pThis, a_GCPtr) ((a_pThis)->f32Bit ? (a_GCPtr) & ~UINT64_C(0xffffffff00000000) : (a_GCPtr))
    9141069
    9151070
     
    12531408
    12541409
     1410/**
     1411 * Fills in the given 32bit NT context structure with the requested values.
     1412 *
     1413 * @returns VBox status code.
     1414 * @param   pThis               The KD context.
     1415 * @param   idCpu               The CPU to query the context for.
     1416 * @param   pNtCtx              The NT context structure to fill in.
     1417 * @param   fCtxFlags           Combination of NTCONTEXT_F_XXX determining what to fill in.
     1418 */
     1419static int dbgcKdCtxQueryNtCtx32(PKDCTX pThis, VMCPUID idCpu, PNTCONTEXT32 pNtCtx, uint32_t fCtxFlags)
     1420{
     1421    RT_BZERO(pNtCtx, sizeof(*pNtCtx));
     1422
     1423    pNtCtx->fContext = NTCONTEXT_F_X86;
     1424
     1425    int rc = VINF_SUCCESS;
     1426    if (fCtxFlags & NTCONTEXT_F_CONTROL)
     1427    {
     1428        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CS, &pNtCtx->u32SegCs);
     1429        if (RT_SUCCESS(rc))
     1430            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_SS, &pNtCtx->u32SegSs);
     1431        if (RT_SUCCESS(rc))
     1432            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EIP, &pNtCtx->u32RegEip);
     1433        if (RT_SUCCESS(rc))
     1434            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_ESP, &pNtCtx->u32RegEsp);
     1435        if (RT_SUCCESS(rc))
     1436            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EBP, &pNtCtx->u32RegEbp);
     1437        if (RT_SUCCESS(rc))
     1438            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EFLAGS, &pNtCtx->u32RegEflags);
     1439        if (RT_SUCCESS(rc))
     1440            pNtCtx->fContext |= NTCONTEXT_F_CONTROL;
     1441    }
     1442
     1443    if (   RT_SUCCESS(rc)
     1444        && fCtxFlags & NTCONTEXT_F_INTEGER)
     1445    {
     1446        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EAX, &pNtCtx->u32RegEax);
     1447        if (RT_SUCCESS(rc))
     1448            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_ECX, &pNtCtx->u32RegEcx);
     1449        if (RT_SUCCESS(rc))
     1450            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EDX, &pNtCtx->u32RegEdx);
     1451        if (RT_SUCCESS(rc))
     1452            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EBX, &pNtCtx->u32RegEbx);
     1453        if (RT_SUCCESS(rc))
     1454            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_ESI, &pNtCtx->u32RegEsi);
     1455        if (RT_SUCCESS(rc))
     1456            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_EDI, &pNtCtx->u32RegEdi);
     1457        if (RT_SUCCESS(rc))
     1458            pNtCtx->fContext |= NTCONTEXT_F_INTEGER;
     1459    }
     1460
     1461    if (   RT_SUCCESS(rc)
     1462        && fCtxFlags & NTCONTEXT_F_SEGMENTS)
     1463    {
     1464        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DS, &pNtCtx->u32SegDs);
     1465        if (RT_SUCCESS(rc))
     1466            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_ES, &pNtCtx->u32SegEs);
     1467        if (RT_SUCCESS(rc))
     1468            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_FS, &pNtCtx->u32SegFs);
     1469        if (RT_SUCCESS(rc))
     1470            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_GS, &pNtCtx->u32SegGs);
     1471        if (RT_SUCCESS(rc))
     1472            pNtCtx->fContext |= NTCONTEXT_F_SEGMENTS;
     1473    }
     1474
     1475    if (   RT_SUCCESS(rc)
     1476        && fCtxFlags & NTCONTEXT_F_FLOATING_POINT)
     1477    {
     1478        /** @todo. */
     1479    }
     1480
     1481    if (   RT_SUCCESS(rc)
     1482        && fCtxFlags & NTCONTEXT_F_DEBUG)
     1483    {
     1484        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR0, &pNtCtx->u32RegDr0);
     1485        if (RT_SUCCESS(rc))
     1486            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR1, &pNtCtx->u32RegDr1);
     1487        if (RT_SUCCESS(rc))
     1488            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR3, &pNtCtx->u32RegDr3);
     1489        if (RT_SUCCESS(rc))
     1490            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR6, &pNtCtx->u32RegDr6);
     1491        if (RT_SUCCESS(rc))
     1492            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR7, &pNtCtx->u32RegDr7);
     1493        if (RT_SUCCESS(rc))
     1494            pNtCtx->fContext |= NTCONTEXT_F_DEBUG;
     1495    }
     1496
     1497    return rc;
     1498}
     1499
     1500
    12551501#define KD_REG_INIT(a_pszName, a_enmType, a_ValMember, a_Val) \
    12561502    do \
     
    14171663
    14181664/**
     1665 * Fills in the given 32bit NT kernel context structure with the requested values.
     1666 *
     1667 * @returns VBox status code.
     1668 * @param   pThis               The KD context.
     1669 * @param   idCpu               The CPU to query the context for.
     1670 * @param   pKNtCtx             The NT context structure to fill in.
     1671 */
     1672static int dbgcKdCtxQueryNtKCtx32(PKDCTX pThis, VMCPUID idCpu, PNTKCONTEXT32 pKNtCtx)
     1673{
     1674    RT_BZERO(pKNtCtx, sizeof(*pKNtCtx));
     1675
     1676    int rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CR0, &pKNtCtx->u32RegCr0);
     1677    if (RT_SUCCESS(rc))
     1678        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CR2, &pKNtCtx->u32RegCr2);
     1679    if (RT_SUCCESS(rc))
     1680        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CR3, &pKNtCtx->u32RegCr3);
     1681    if (RT_SUCCESS(rc))
     1682        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_CR4, &pKNtCtx->u32RegCr4);
     1683
     1684    if (RT_SUCCESS(rc))
     1685        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR0, &pKNtCtx->u32RegDr0);
     1686    if (RT_SUCCESS(rc))
     1687        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR1, &pKNtCtx->u32RegDr1);
     1688    if (RT_SUCCESS(rc))
     1689        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR2, &pKNtCtx->u32RegDr2);
     1690    if (RT_SUCCESS(rc))
     1691        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR3, &pKNtCtx->u32RegDr3);
     1692    if (RT_SUCCESS(rc))
     1693        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR6, &pKNtCtx->u32RegDr6);
     1694    if (RT_SUCCESS(rc))
     1695        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_DR7, &pKNtCtx->u32RegDr7);
     1696    if (RT_SUCCESS(rc))
     1697        rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_GDTR_LIMIT, &pKNtCtx->Gdtr.u16Limit);
     1698    if (RT_SUCCESS(rc))
     1699        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_GDTR_BASE, &pKNtCtx->Gdtr.u32PtrBase);
     1700    if (RT_SUCCESS(rc))
     1701        rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_IDTR_LIMIT, &pKNtCtx->Idtr.u16Limit);
     1702    if (RT_SUCCESS(rc))
     1703        rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, idCpu, DBGFREG_IDTR_BASE, &pKNtCtx->Idtr.u32PtrBase);
     1704    if (RT_SUCCESS(rc))
     1705        rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_TR, &pKNtCtx->u16RegTr);
     1706    if (RT_SUCCESS(rc))
     1707        rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, idCpu, DBGFREG_LDTR, &pKNtCtx->u16RegLdtr);
     1708
     1709    return rc;
     1710}
     1711
     1712
     1713/**
    14191714 * Fills in the given 64bit NT kernel context structure with the requested values.
    14201715 *
     
    18022097    /* Select the record to send based on the CPU mode. */
    18032098    int rc = VINF_SUCCESS;
    1804     CPUMMODE enmMode = DBGCCmdHlpGetCpuMode(&pThis->Dbgc.CmdHlp);
    1805     switch (enmMode)
    1806     {
    1807         case CPUMMODE_PROTECTED:
    1808         {
    1809             break;
    1810         }
    1811         case CPUMMODE_LONG:
    1812         {
    1813             KDPACKETSTATECHANGE64 StateChange64;
    1814             RT_ZERO(StateChange64);
    1815 
    1816             StateChange64.u32StateNew = KD_PACKET_STATE_CHANGE_EXCEPTION;
    1817             StateChange64.u16CpuLvl   = 0x6; /** @todo Figure this one out. */
    1818             StateChange64.idCpu       = pThis->Dbgc.idCpu;
    1819             StateChange64.cCpus       = (uint16_t)DBGFR3CpuGetCount(pThis->Dbgc.pUVM);
    1820             rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_RIP, &StateChange64.u64RipThread);
    1821             if (RT_SUCCESS(rc))
    1822             {
    1823                 /** @todo Properly fill in the exception record. */
    1824                 switch (enmType)
    1825                 {
    1826                     case DBGFEVENT_HALT_DONE:
    1827                     case DBGFEVENT_BREAKPOINT:
    1828                     case DBGFEVENT_BREAKPOINT_IO:
    1829                     case DBGFEVENT_BREAKPOINT_MMIO:
    1830                     case DBGFEVENT_BREAKPOINT_HYPER:
    1831                         StateChange64.u.Exception.ExcpRec.u32ExcpCode = KD_PACKET_EXCP_CODE_BKPT;
    1832                         break;
    1833                     case DBGFEVENT_STEPPED:
    1834                     case DBGFEVENT_STEPPED_HYPER:
    1835                         StateChange64.u.Exception.ExcpRec.u32ExcpCode = KD_PACKET_EXCP_CODE_SINGLE_STEP;
    1836                         break;
    1837                     default:
    1838                         AssertMsgFailed(("Invalid DBGF event type for state change %d!\n", enmType));
    1839                 }
    1840 
    1841                 StateChange64.u.Exception.ExcpRec.cExcpParms = 3;
    1842                 StateChange64.u.Exception.u32FirstChance     = 0x1;
    1843 
    1844                 /** @todo Properly fill in the control report. */
    1845                 rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DR6, &StateChange64.uCtrlReport.Amd64.u64RegDr6);
    1846                 if (RT_SUCCESS(rc))
    1847                     rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DR7, &StateChange64.uCtrlReport.Amd64.u64RegDr7);
    1848                 if (RT_SUCCESS(rc))
    1849                     rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_RFLAGS, &StateChange64.uCtrlReport.Amd64.u32RegEflags);
    1850                 if (RT_SUCCESS(rc))
    1851                     rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_CS, &StateChange64.uCtrlReport.Amd64.u16SegCs);
    1852                 if (RT_SUCCESS(rc))
    1853                     rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DS, &StateChange64.uCtrlReport.Amd64.u16SegDs);
    1854                 if (RT_SUCCESS(rc))
    1855                     rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_ES, &StateChange64.uCtrlReport.Amd64.u16SegEs);
    1856                 if (RT_SUCCESS(rc))
    1857                     rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_FS, &StateChange64.uCtrlReport.Amd64.u16SegFs);
    1858 
    1859                 /* Read instruction bytes. */
    1860                 StateChange64.uCtrlReport.Amd64.cbInsnStream = sizeof(StateChange64.uCtrlReport.Amd64.abInsn);
    1861                 DBGFADDRESS AddrRip;
    1862                 DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrRip, StateChange64.u64RipThread);
    1863                 rc = DBGFR3MemRead(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, &AddrRip,
    1864                                    &StateChange64.uCtrlReport.Amd64.abInsn[0], StateChange64.uCtrlReport.Amd64.cbInsnStream);
    1865                 if (RT_SUCCESS(rc))
    1866                 {
    1867                     pThis->idPktNext = KD_PACKET_HDR_ID_INITIAL;
    1868                     rc = dbgcKdCtxPktSend(pThis, KD_PACKET_HDR_SIGNATURE_DATA, KD_PACKET_HDR_SUB_TYPE_STATE_CHANGE64,
    1869                                           &StateChange64, sizeof(StateChange64), false /*fAck*/);
    1870                 }
    1871             }
    1872             break;
    1873         }
    1874         case CPUMMODE_REAL:
    1875         default:
    1876             return DBGCCmdHlpPrintf(&pThis->Dbgc.CmdHlp, "error: Invalid CPU mode %d.\n", enmMode);
     2099    KDPACKETSTATECHANGE64 StateChange64;
     2100    RT_ZERO(StateChange64);
     2101
     2102    StateChange64.u32StateNew = KD_PACKET_STATE_CHANGE_EXCEPTION;
     2103    StateChange64.u16CpuLvl   = 0x6; /** @todo Figure this one out. */
     2104    StateChange64.idCpu       = pThis->Dbgc.idCpu;
     2105    StateChange64.cCpus       = (uint16_t)DBGFR3CpuGetCount(pThis->Dbgc.pUVM);
     2106    rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_RIP, &StateChange64.u64RipThread);
     2107    if (RT_SUCCESS(rc))
     2108    {
     2109        DBGFADDRESS AddrRip;
     2110        DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrRip, StateChange64.u64RipThread);
     2111
     2112        StateChange64.u64RipThread = KD_PTR_CREATE(pThis, StateChange64.u64RipThread);
     2113
     2114        /** @todo Properly fill in the exception record. */
     2115        switch (enmType)
     2116        {
     2117            case DBGFEVENT_HALT_DONE:
     2118            case DBGFEVENT_BREAKPOINT:
     2119            case DBGFEVENT_BREAKPOINT_IO:
     2120            case DBGFEVENT_BREAKPOINT_MMIO:
     2121            case DBGFEVENT_BREAKPOINT_HYPER:
     2122                StateChange64.u.Exception.ExcpRec.u32ExcpCode = KD_PACKET_EXCP_CODE_BKPT;
     2123                break;
     2124            case DBGFEVENT_STEPPED:
     2125            case DBGFEVENT_STEPPED_HYPER:
     2126                StateChange64.u.Exception.ExcpRec.u32ExcpCode = KD_PACKET_EXCP_CODE_SINGLE_STEP;
     2127                break;
     2128            default:
     2129                AssertMsgFailed(("Invalid DBGF event type for state change %d!\n", enmType));
     2130        }
     2131
     2132        StateChange64.u.Exception.ExcpRec.cExcpParms = 3;
     2133        StateChange64.u.Exception.u32FirstChance     = 0x1;
     2134
     2135        /** @todo Properly fill in the control report. */
     2136        rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DR6, &StateChange64.uCtrlReport.Amd64.u64RegDr6);
     2137        if (RT_SUCCESS(rc))
     2138            rc = DBGFR3RegCpuQueryU64(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DR7, &StateChange64.uCtrlReport.Amd64.u64RegDr7);
     2139        if (RT_SUCCESS(rc))
     2140            rc = DBGFR3RegCpuQueryU32(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_RFLAGS, &StateChange64.uCtrlReport.Amd64.u32RegEflags);
     2141        if (RT_SUCCESS(rc))
     2142            rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_CS, &StateChange64.uCtrlReport.Amd64.u16SegCs);
     2143        if (RT_SUCCESS(rc))
     2144            rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_DS, &StateChange64.uCtrlReport.Amd64.u16SegDs);
     2145        if (RT_SUCCESS(rc))
     2146            rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_ES, &StateChange64.uCtrlReport.Amd64.u16SegEs);
     2147        if (RT_SUCCESS(rc))
     2148            rc = DBGFR3RegCpuQueryU16(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, DBGFREG_FS, &StateChange64.uCtrlReport.Amd64.u16SegFs);
     2149
     2150        /* Read instruction bytes. */
     2151        StateChange64.uCtrlReport.Amd64.cbInsnStream = sizeof(StateChange64.uCtrlReport.Amd64.abInsn);
     2152        rc = DBGFR3MemRead(pThis->Dbgc.pUVM, pThis->Dbgc.idCpu, &AddrRip,
     2153                           &StateChange64.uCtrlReport.Amd64.abInsn[0], StateChange64.uCtrlReport.Amd64.cbInsnStream);
     2154        if (RT_SUCCESS(rc))
     2155        {
     2156            pThis->idPktNext = KD_PACKET_HDR_ID_INITIAL;
     2157            rc = dbgcKdCtxPktSend(pThis, KD_PACKET_HDR_SIGNATURE_DATA, KD_PACKET_HDR_SUB_TYPE_STATE_CHANGE64,
     2158                                  &StateChange64, sizeof(StateChange64), false /*fAck*/);
     2159        }
    18772160    }
    18782161
     
    19172200    Resp.u.GetVersion.u16VersMin             = NtBuildNumber & UINT32_C(0xffff);
    19182201    Resp.u.GetVersion.u8VersProtocol         = 0x6; /* From a Windows 10 guest. */
    1919     Resp.u.GetVersion.u8VersKdSecondary      = 0x2; /* From a Windows 10 guest. */
     2202    Resp.u.GetVersion.u8VersKdSecondary      = pThis->f32Bit ? 0 : 0x2; /* amd64 has a versioned context (0 and 1 are obsolete). */
    19202203    Resp.u.GetVersion.fFlags                 = KD_PACKET_MANIPULATE64_GET_VERSION_F_MP;
    19212204    Resp.u.GetVersion.u8MaxPktType           = KD_PACKET_HDR_SUB_TYPE_MAX;
     
    19252208
    19262209    if (f32Bit)
    1927         Resp.u.GetVersion.u16MachineType = IMAGE_FILE_MACHINE_I386;
     2210    {
     2211        Resp.u.GetVersion.u16MachineType           = IMAGE_FILE_MACHINE_I386;
     2212        Resp.u.GetVersion.u64PtrKernBase           = KD_PTR_CREATE(pThis, Resp.u.GetVersion.u64PtrKernBase);
     2213        Resp.u.GetVersion.u64PtrPsLoadedModuleList = KD_PTR_CREATE(pThis, Resp.u.GetVersion.u64PtrPsLoadedModuleList);
     2214    }
    19282215    else
    19292216    {
     
    19542241    uint32_t cbRead = RT_MIN(sizeof(abMem), pPktManip->u.XferMem.cbXferReq);
    19552242    if (pPktManip->Hdr.idReq == KD_PACKET_MANIPULATE_REQ_READ_VIRT_MEM)
    1956         DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrRead, pPktManip->u.XferMem.u64PtrTarget);
     2243        DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrRead, KD_PTR_GET(pThis, pPktManip->u.XferMem.u64PtrTarget));
    19572244    else
    1958         DBGFR3AddrFromPhys(pThis->Dbgc.pUVM, &AddrRead, pPktManip->u.XferMem.u64PtrTarget);
     2245        DBGFR3AddrFromPhys(pThis->Dbgc.pUVM, &AddrRead, KD_PTR_GET(pThis, pPktManip->u.XferMem.u64PtrTarget));
    19592246
    19602247    RTSGSEG aRespSegs[3];
     
    20062293    uint32_t cbWrite = RT_MIN(sizeof(pThis->abBody) - sizeof(*pPktManip), pPktManip->u.XferMem.cbXferReq);
    20072294    if (pPktManip->Hdr.idReq == KD_PACKET_MANIPULATE_REQ_WRITE_VIRT_MEM)
    2008         DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrWrite, pPktManip->u.XferMem.u64PtrTarget);
     2295        DBGFR3AddrFromFlat(pThis->Dbgc.pUVM, &AddrWrite, KD_PTR_GET(pThis, pPktManip->u.XferMem.u64PtrTarget));
    20092296    else
    2010         DBGFR3AddrFromPhys(pThis->Dbgc.pUVM, &AddrWrite, pPktManip->u.XferMem.u64PtrTarget);
     2297        DBGFR3AddrFromPhys(pThis->Dbgc.pUVM, &AddrWrite, KD_PTR_GET(pThis, pPktManip->u.XferMem.u64PtrTarget));
    20112298
    20122299    RTSGSEG aRespSegs[2];
     
    21532440
    21542441    int rc = VINF_SUCCESS;
    2155     switch (pPktManip->u.XferCtrlSpace.u64IdXfer)
    2156     {
    2157         case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KPCR:
    2158         {
    2159             if (pThis->pIfWinNt)
     2442    if (pThis->f32Bit)
     2443    {
     2444        if (pPktManip->u.XferCtrlSpace.u64IdXfer == sizeof(NTCONTEXT32))
     2445        {
     2446            /* Queries the kernel context. */
     2447            rc = dbgcKdCtxQueryNtKCtx32(pThis, RespHdr.idCpu, (PNTKCONTEXT32)&abResp[0]);
     2448            if (RT_SUCCESS(rc))
     2449                cbData = sizeof(NTKCONTEXT32);
     2450        }
     2451    }
     2452    else
     2453    {
     2454        switch (pPktManip->u.XferCtrlSpace.u64IdXfer)
     2455        {
     2456            case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KPCR:
    21602457            {
    2161                 RTGCUINTPTR GCPtrKpcr = 0;
    2162 
    2163                 rc = pThis->pIfWinNt->pfnQueryKpcrForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu,
    2164                                                           &GCPtrKpcr, NULL /*pKpcrb*/);
     2458                if (pThis->pIfWinNt)
     2459                {
     2460                    RTGCUINTPTR GCPtrKpcr = 0;
     2461
     2462                    rc = pThis->pIfWinNt->pfnQueryKpcrForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu,
     2463                                                              &GCPtrKpcr, NULL /*pKpcrb*/);
     2464                    if (RT_SUCCESS(rc))
     2465                        memcpy(&abResp[0], &GCPtrKpcr, sizeof(GCPtrKpcr));
     2466                }
     2467
     2468                cbData = sizeof(RTGCUINTPTR);
     2469                break;
     2470            }
     2471            case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KPCRB:
     2472            {
     2473                if (pThis->pIfWinNt)
     2474                {
     2475                    RTGCUINTPTR GCPtrKpcrb = 0;
     2476
     2477                    rc = pThis->pIfWinNt->pfnQueryKpcrForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu,
     2478                                                              NULL /*pKpcr*/, &GCPtrKpcrb);
     2479                    if (RT_SUCCESS(rc))
     2480                        memcpy(&abResp[0], &GCPtrKpcrb, sizeof(GCPtrKpcrb));
     2481                }
     2482
     2483                cbData = sizeof(RTGCUINTPTR);
     2484                break;
     2485            }
     2486            case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KCTX:
     2487            {
     2488                rc = dbgcKdCtxQueryNtKCtx64(pThis, RespHdr.idCpu, (PNTKCONTEXT64)&abResp[0], NTCONTEXT64_F_FULL);
    21652489                if (RT_SUCCESS(rc))
    2166                     memcpy(&abResp[0], &GCPtrKpcr, sizeof(GCPtrKpcr));
     2490                    cbData = sizeof(NTKCONTEXT64);
     2491                break;
    21672492            }
    2168 
    2169             cbData = sizeof(RTGCUINTPTR);
    2170             break;
    2171         }
    2172         case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KPCRB:
    2173         {
    2174             if (pThis->pIfWinNt)
     2493            case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KTHRD:
    21752494            {
    2176                 RTGCUINTPTR GCPtrKpcrb = 0;
    2177 
    2178                 rc = pThis->pIfWinNt->pfnQueryKpcrForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu,
    2179                                                           NULL /*pKpcr*/, &GCPtrKpcrb);
    2180                 if (RT_SUCCESS(rc))
    2181                     memcpy(&abResp[0], &GCPtrKpcrb, sizeof(GCPtrKpcrb));
     2495                if (pThis->pIfWinNt)
     2496                {
     2497                    RTGCUINTPTR GCPtrCurThrd = 0;
     2498
     2499                    rc = pThis->pIfWinNt->pfnQueryCurThrdForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu,
     2500                                                                 &GCPtrCurThrd);
     2501                    if (RT_SUCCESS(rc))
     2502                        memcpy(&abResp[0], &GCPtrCurThrd, sizeof(GCPtrCurThrd));
     2503                }
     2504
     2505                cbData = sizeof(RTGCUINTPTR);
     2506                break;
    21822507            }
    2183 
    2184             cbData = sizeof(RTGCUINTPTR);
    2185             break;
    2186         }
    2187         case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KCTX:
    2188         {
    2189             rc = dbgcKdCtxQueryNtKCtx64(pThis, RespHdr.idCpu, (PNTKCONTEXT64)&abResp[0], NTCONTEXT64_F_FULL);
    2190             if (RT_SUCCESS(rc))
    2191                 cbData = sizeof(NTKCONTEXT64);
    2192             break;
    2193         }
    2194         case KD_PACKET_MANIPULATE64_CTRL_SPACE_ID_KTHRD:
    2195         {
    2196             if (pThis->pIfWinNt)
    2197             {
    2198                 RTGCUINTPTR GCPtrCurThrd = 0;
    2199 
    2200                 rc = pThis->pIfWinNt->pfnQueryCurThrdForVCpu(pThis->pIfWinNt, pThis->Dbgc.pUVM, RespHdr.idCpu,
    2201                                                              &GCPtrCurThrd);
    2202                 if (RT_SUCCESS(rc))
    2203                     memcpy(&abResp[0], &GCPtrCurThrd, sizeof(GCPtrCurThrd));
    2204             }
    2205 
    2206             cbData = sizeof(RTGCUINTPTR);
    2207             break;
    2208         }
    2209         default:
    2210             rc = VERR_NOT_SUPPORTED;
    2211             break;
     2508            default:
     2509                rc = VERR_NOT_SUPPORTED;
     2510                break;
     2511        }
    22122512    }
    22132513
     
    23712671    KDPACKETMANIPULATEHDR RespHdr;
    23722672    KDPACKETMANIPULATE_CONTEXTEX ContextEx;
    2373     NTCONTEXT64 NtCtx;
    2374     RT_ZERO(RespHdr); RT_ZERO(ContextEx);
     2673    union
     2674    {
     2675        NTCONTEXT64 v64;
     2676        NTCONTEXT32 v32;
     2677    } NtCtx;
     2678    RT_ZERO(RespHdr); RT_ZERO(ContextEx); RT_ZERO(NtCtx);
    23752679
    23762680    RTSGSEG aRespSegs[3];
     
    23902694    aRespSegs[1].cbSeg = sizeof(ContextEx);
    23912695
    2392     int rc = dbgcKdCtxQueryNtCtx64(pThis, pPktManip->Hdr.idCpu, &NtCtx, NTCONTEXT64_F_FULL);
     2696    int rc = VINF_SUCCESS;
     2697    size_t cbCtx = pThis->f32Bit ? sizeof(NtCtx.v32) : sizeof(NtCtx.v64);
     2698    if (pThis->f32Bit)
     2699        dbgcKdCtxQueryNtCtx32(pThis, pPktManip->Hdr.idCpu, &NtCtx.v32, NTCONTEXT32_F_FULL);
     2700    else
     2701        dbgcKdCtxQueryNtCtx64(pThis, pPktManip->Hdr.idCpu, &NtCtx.v64, NTCONTEXT64_F_FULL);
    23932702    if (   RT_SUCCESS(rc)
    2394         && pPktManip->u.ContextEx.offStart < sizeof(NtCtx))
     2703        && pPktManip->u.ContextEx.offStart < cbCtx)
    23952704    {
    23962705        RespHdr.u32NtStatus = NTSTATUS_SUCCESS;
    2397         ContextEx.cbXfered = RT_MIN(sizeof(NtCtx) - ContextEx.offStart, ContextEx.cbXfer);
     2706        ContextEx.cbXfered = RT_MIN(cbCtx - ContextEx.offStart, ContextEx.cbXfer);
    23982707
    23992708        aRespSegs[2].pvSeg = (uint8_t *)&NtCtx + ContextEx.offStart;
     
    25442853                case KD_PACKET_HDR_SUB_TYPE_STATE_MANIPULATE:
    25452854                {
    2546                     CPUMMODE enmMode = DBGCCmdHlpGetCpuMode(&pThis->Dbgc.CmdHlp);
    2547                     switch (enmMode)
    2548                     {
    2549                         case CPUMMODE_PROTECTED:
    2550                         {
    2551                             rc = VERR_NOT_IMPLEMENTED;
    2552                             break;
    2553                         }
    2554                         case CPUMMODE_LONG:
    2555                         {
    2556                             pThis->idPktNext = pThis->PktHdr.Fields.idPacket ^ 0x1;
    2557                             rc = dbgcKdCtxPktManipulate64Process(pThis);
    2558                             break;
    2559                         }
    2560                         case CPUMMODE_REAL:
    2561                         default:
    2562                             rc = VERR_NOT_SUPPORTED;
    2563                             break;
    2564                     }
     2855                    pThis->idPktNext = pThis->PktHdr.Fields.idPacket ^ 0x1;
     2856                    rc = dbgcKdCtxPktManipulate64Process(pThis);
    25652857                    break;
    25662858                }
     
    30983390    pThis->idPktNext    = KD_PACKET_HDR_ID_INITIAL;
    30993391    pThis->pIfWinNt     = NULL;
     3392    pThis->f32Bit       = false;
    31003393    dbgcKdCtxPktRecvReset(pThis);
    31013394
     
    31853478                rc = VINF_SUCCESS; /* Try to continue nevertheless. */
    31863479            }
     3480
     3481            if (pThis->pIfWinNt)
     3482            {
     3483                rc = pThis->pIfWinNt->pfnQueryVersion(pThis->pIfWinNt, pThis->Dbgc.pUVM,
     3484                                                      NULL /*puVersMajor*/, NULL /*puVersMinor*/,
     3485                                                      NULL /*puBuildNumber*/, &pThis->f32Bit);
     3486                AssertRC(rc);
     3487            }
     3488            else
     3489            {
     3490                /*
     3491                 * Try to detect bitness based on the current CPU mode which might fool us (32bit process running
     3492                 * inside of 64bit host).
     3493                 */
     3494                CPUMMODE enmMode = DBGCCmdHlpGetCpuMode(&pThis->Dbgc.CmdHlp);
     3495                if (enmMode == CPUMMODE_PROTECTED)
     3496                    pThis->f32Bit = true;
     3497                else if (enmMode == CPUMMODE_LONG)
     3498                    pThis->f32Bit = false;
     3499                else
     3500                    LogRel(("DBGC/Kd: Heh, trying to debug real mode code with WinDbg are we? Good luck with that...\n"));
     3501            }
    31873502        }
    31883503        else
Note: See TracChangeset for help on using the changeset viewer.

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