コード例 #1
0
/**
 * Disarms an int 3 breakpoint.
 * This is used to implement both DBGFR3BpClear() and DBGFR3BpDisable().
 *
 * @returns VBox status code.
 * @param   pVM         The VM handle.
 * @param   pBp         The breakpoint.
 */
static int dbgfR3BpInt3Disarm(PVM pVM, PDBGFBP pBp)
{
    /* @todo SMP support! */
    VMCPUID idCpu = 0;

    /*
     * Check that the current byte is the int3 instruction, and restore the original one.
     * We currently ignore invalid bytes.
     */
    DBGFADDRESS     Addr;
    DBGFR3AddrFromFlat(pVM, &Addr, pBp->GCPtr);
    uint8_t         bCurrent;
    int rc = DBGFR3MemRead(pVM, idCpu, &Addr, &bCurrent, 1);
    if (bCurrent == 0xcc)
        rc = DBGFR3MemWrite(pVM, idCpu, &Addr, &pBp->u.Int3.bOrg, 1);
    return rc;
}
コード例 #2
0
/**
 * Arms an int 3 breakpoint.
 * This is used to implement both DBGFR3BpSetReg() and DBGFR3BpEnable().
 *
 * @returns VBox status code.
 * @param   pVM         The VM handle.
 * @param   pBp         The breakpoint.
 */
static int dbgfR3BpInt3Arm(PVM pVM, PDBGFBP pBp)
{
    /** @todo should actually use physical address here! */

    /* @todo SMP support! */
    VMCPUID idCpu = 0;

    /*
     * Save current byte and write int3 instruction.
     */
    DBGFADDRESS Addr;
    DBGFR3AddrFromFlat(pVM, &Addr, pBp->GCPtr);
    int rc = DBGFR3MemRead(pVM, idCpu, &Addr, &pBp->u.Int3.bOrg, 1);
    if (RT_SUCCESS(rc))
    {
        static const uint8_t s_bInt3 = 0xcc;
        rc = DBGFR3MemWrite(pVM, idCpu, &Addr, &s_bInt3, 1);
    }
    return rc;
}
コード例 #3
0
ファイル: DBGCCmdHlp.cpp プロジェクト: mutoso-mirrors/vbox
/**
 * @interface_method_impl{DBGCCMDHLP,pfnMemWrite}
 */
static DECLCALLBACK(int) dbgcHlpMemWrite(PDBGCCMDHLP pCmdHlp, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten)
{
    PDBGC       pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
    DBGFADDRESS Address;
    int         rc;

    /*
     * Dummy check.
     */
    if (cbWrite == 0)
    {
        if (*pcbWritten)
            *pcbWritten = 0;
        return VINF_SUCCESS;
    }

    /*
     * Convert Far addresses getting size and the correct base address.
     * Getting and checking the size is what makes this messy and slow.
     */
    DBGCVAR Var = *pVarPointer;
    switch (pVarPointer->enmType)
    {
        case DBGCVAR_TYPE_GC_FAR:
        {
            /* Use DBGFR3AddrFromSelOff for the conversion. */
            Assert(pDbgc->pUVM);
            rc = DBGFR3AddrFromSelOff(pDbgc->pUVM, pDbgc->idCpu, &Address, Var.u.GCFar.sel, Var.u.GCFar.off);
            if (RT_FAILURE(rc))
                return rc;

            /* don't bother with flat selectors (for now). */
            if (!DBGFADDRESS_IS_FLAT(&Address))
            {
                DBGFSELINFO SelInfo;
                rc = DBGFR3SelQueryInfo(pDbgc->pUVM, pDbgc->idCpu, Address.Sel,
                                        DBGFSELQI_FLAGS_DT_GUEST | DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE, &SelInfo);
                if (RT_SUCCESS(rc))
                {
                    RTGCUINTPTR cb; /* -1 byte */
                    if (DBGFSelInfoIsExpandDown(&SelInfo))
                    {
                        if (    !SelInfo.u.Raw.Gen.u1Granularity
                            &&  Address.off > UINT16_C(0xffff))
                            return VERR_OUT_OF_SELECTOR_BOUNDS;
                        if (Address.off <= SelInfo.cbLimit)
                            return VERR_OUT_OF_SELECTOR_BOUNDS;
                        cb = (SelInfo.u.Raw.Gen.u1Granularity ? UINT32_C(0xffffffff) : UINT32_C(0xffff)) - Address.off;
                    }
                    else
                    {
                        if (Address.off > SelInfo.cbLimit)
                            return VERR_OUT_OF_SELECTOR_BOUNDS;
                        cb = SelInfo.cbLimit - Address.off;
                    }
                    if (cbWrite - 1 > cb)
                    {
                        if (!pcbWritten)
                            return VERR_OUT_OF_SELECTOR_BOUNDS;
                        cbWrite = cb + 1;
                    }
                }
            }
            Var.enmType = DBGCVAR_TYPE_GC_FLAT;
            Var.u.GCFlat = Address.FlatPtr;
        }
        /* fall thru */
        case DBGCVAR_TYPE_GC_FLAT:
            rc = DBGFR3MemWrite(pDbgc->pUVM, pDbgc->idCpu,
                                DBGFR3AddrFromFlat(pDbgc->pUVM, &Address, Var.u.GCFlat),
                                pvBuffer, cbWrite);
            if (pcbWritten && RT_SUCCESS(rc))
                *pcbWritten = cbWrite;
            return rc;

        case DBGCVAR_TYPE_GC_PHYS:
            rc = DBGFR3MemWrite(pDbgc->pUVM, pDbgc->idCpu,
                                DBGFR3AddrFromPhys(pDbgc->pUVM, &Address, Var.u.GCPhys),
                                pvBuffer, cbWrite);
            if (pcbWritten && RT_SUCCESS(rc))
                *pcbWritten = cbWrite;
            return rc;

        case DBGCVAR_TYPE_HC_FLAT:
        case DBGCVAR_TYPE_HC_PHYS:
        {
            /*
             * Copy HC memory page by page.
             */
            if (pcbWritten)
                *pcbWritten = 0;
            while (cbWrite > 0)
            {
                /* convert to flat address */
                DBGCVAR Var2;
                rc = dbgcOpAddrFlat(pDbgc, &Var, DBGCVAR_CAT_ANY, &Var2);
                if (RT_FAILURE(rc))
                {
                    if (pcbWritten && *pcbWritten)
                        return -VERR_INVALID_POINTER;
                    return VERR_INVALID_POINTER;
                }

                /* calc size. */
                size_t cbChunk = PAGE_SIZE;
                cbChunk -= (uintptr_t)Var.u.pvHCFlat & PAGE_OFFSET_MASK;
                if (cbChunk > cbWrite)
                    cbChunk = cbWrite;

                /** @todo protect this!!! */
                memcpy(Var2.u.pvHCFlat, pvBuffer, cbChunk);

                /* advance */
                if (Var.enmType == DBGCVAR_TYPE_HC_FLAT)
                    Var.u.pvHCFlat = (uint8_t *)Var.u.pvHCFlat + cbChunk;
                else
                    Var.u.HCPhys += cbChunk;
                pvBuffer = (uint8_t const *)pvBuffer + cbChunk;
                if (pcbWritten)
                    *pcbWritten += cbChunk;
                cbWrite -= cbChunk;
            }

            return VINF_SUCCESS;
        }

        default:
            return VERR_NOT_IMPLEMENTED;
    }
}