Пример #1
0
/**
 * @callback_method_impl{FNDBGCOPUNARY, Far address (unary).}
 */
static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
    LogFlow(("dbgcOpAddrFar\n"));
    int     rc;

    switch (pArg1->enmType)
    {
        case DBGCVAR_TYPE_SYMBOL:
            rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_NUMBER, pResult);
            if (RT_FAILURE(rc))
                return rc;
            break;
        case DBGCVAR_TYPE_NUMBER:
            *pResult = *pArg1;
            break;
        default:
            return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;
    }
    pResult->u.GCFar.sel = (RTSEL)pResult->u.u64Number;

    /* common code for the two types we support. */
    switch (pArg2->enmType)
    {
        case DBGCVAR_TYPE_GC_FLAT:
            pResult->u.GCFar.off = pArg2->u.GCFlat;
            pResult->enmType    = DBGCVAR_TYPE_GC_FAR;
            break;

        case DBGCVAR_TYPE_HC_FLAT:
            pResult->u.pvHCFlat = (void *)(uintptr_t)pArg2->u.GCFlat;
            pResult->enmType    = DBGCVAR_TYPE_GC_FAR;
            break;

        case DBGCVAR_TYPE_NUMBER:
            pResult->u.GCFar.off = (RTGCPTR)pArg2->u.u64Number;
            pResult->enmType    = DBGCVAR_TYPE_GC_FAR;
            break;

        case DBGCVAR_TYPE_SYMBOL:
        {
            DBGCVAR Var;
            rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
            if (RT_FAILURE(rc))
                return rc;
            pResult->u.GCFar.off = (RTGCPTR)Var.u.u64Number;
            pResult->enmType    = DBGCVAR_TYPE_GC_FAR;
            break;
        }

        default:
            return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;
    }
    return VINF_SUCCESS;

}
Пример #2
0
/**
 * Range to operator (binary).
 *
 * @returns VINF_SUCCESS on success.
 * @returns VBox evaluation / parsing error code on failure.
 *          The caller does the bitching.
 * @param   pDbgc       Debugger console instance data.
 * @param   pArg1       The first argument.
 * @param   pArg2       The 2nd argument.
 * @param   pResult     Where to store the result.
 */
static DECLCALLBACK(int) dbgcOpRangeLength(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
    LogFlow(("dbgcOpRangeLength\n"));

    if (pArg1->enmType == DBGCVAR_TYPE_STRING)
        return VERR_DBGC_PARSE_INVALID_OPERATION;

    /*
     * Make result. Symbols needs to be resolved.
     */
    if (pArg1->enmType == DBGCVAR_TYPE_SYMBOL)
    {
        int rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_ANY, pResult);
        if (RT_FAILURE(rc))
            return rc;
    }
    else
        *pResult = *pArg1;

    /*
     * Convert 2nd argument to element count.
     */
    pResult->enmRangeType = DBGCVAR_RANGE_ELEMENTS;
    switch (pArg2->enmType)
    {
        case DBGCVAR_TYPE_NUMBER:
            pResult->u64Range = pArg2->u.u64Number;
            break;

        case DBGCVAR_TYPE_SYMBOL:
        {
            int rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, pResult);
            if (RT_FAILURE(rc))
                return rc;
            pResult->u64Range = pArg2->u.u64Number;
            break;
        }

        case DBGCVAR_TYPE_STRING:
        default:
            return VERR_DBGC_PARSE_INVALID_OPERATION;
    }

    return VINF_SUCCESS;
}
Пример #3
0
/**
 * Converts an argument to a number value.
 *
 * @returns VBox status code.
 * @param   pDbgc               The DBGC instance.
 * @param   pArg                The argument to convert.
 * @param   pu64Ret             Where to return the value.
 */
static int dbgcOpHelperGetNumber(PDBGC pDbgc, PCDBGCVAR pArg, uint64_t *pu64Ret)
{
    DBGCVAR Var = *pArg;
    switch (Var.enmType)
    {
        case DBGCVAR_TYPE_GC_FLAT:
            *pu64Ret = Var.u.GCFlat;
            break;
        case DBGCVAR_TYPE_GC_FAR:
            *pu64Ret = Var.u.GCFar.off;
            break;
        case DBGCVAR_TYPE_GC_PHYS:
            *pu64Ret = Var.u.GCPhys;
            break;
        case DBGCVAR_TYPE_HC_FLAT:
            *pu64Ret = (uintptr_t)Var.u.pvHCFlat;
            break;
        case DBGCVAR_TYPE_HC_PHYS:
            *pu64Ret = Var.u.HCPhys;
            break;
        case DBGCVAR_TYPE_NUMBER:
            *pu64Ret = Var.u.u64Number;
            break;
        case DBGCVAR_TYPE_SYMBOL:
        {
            int rc = dbgcSymbolGet(pDbgc, Var.u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
            if (RT_FAILURE(rc))
                return rc;
            /* fall thru */
        }
        case DBGCVAR_TYPE_STRING:
        default:
            return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;
    }
    return VINF_SUCCESS;
}
Пример #4
0
/**
 * @interface_method_impl{DBGCCMDHLP,pfnVarConvert}
 */
static DECLCALLBACK(int) dbgcHlpVarConvert(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pInVar, DBGCVARTYPE enmToType, bool fConvSyms,
                                           PDBGCVAR pResult)
{
    PDBGC           pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp);
    DBGCVAR const   InVar = *pInVar;    /* if pInVar == pResult  */
    PCDBGCVAR       pArg = &InVar;      /* lazy bird, clean up later */
    DBGFADDRESS     Address;
    int             rc;

    Assert(pDbgc->pUVM);

    *pResult = InVar;
    switch (InVar.enmType)
    {
        case DBGCVAR_TYPE_GC_FLAT:
            switch (enmToType)
            {
                case DBGCVAR_TYPE_GC_FLAT:
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_GC_FAR:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_GC_PHYS:
                    pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
                    rc = DBGFR3AddrToPhys(pDbgc->pUVM, pDbgc->idCpu,
                                          DBGFR3AddrFromFlat(pDbgc->pUVM, &Address, pArg->u.GCFlat),
                                          &pResult->u.GCPhys);
                    if (RT_SUCCESS(rc))
                        return VINF_SUCCESS;
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_HC_FLAT:
                    pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
                    rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pUVM, pDbgc->idCpu,
                                                   DBGFR3AddrFromFlat(pDbgc->pUVM, &Address, pArg->u.GCFlat),
                                                   false /*fReadOnly */,
                                                   &pResult->u.pvHCFlat);
                    if (RT_SUCCESS(rc))
                        return VINF_SUCCESS;
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_HC_PHYS:
                    pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
                    rc = DBGFR3AddrToHostPhys(pDbgc->pUVM, pDbgc->idCpu,
                                              DBGFR3AddrFromFlat(pDbgc->pUVM, &Address, pArg->u.GCFlat),
                                              &pResult->u.GCPhys);
                    if (RT_SUCCESS(rc))
                        return VINF_SUCCESS;
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_NUMBER:
                    pResult->enmType     = enmToType;
                    pResult->u.u64Number = InVar.u.GCFlat;
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_STRING:
                case DBGCVAR_TYPE_SYMBOL:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_UNKNOWN:
                case DBGCVAR_TYPE_ANY:
                    break;
            }
            break;

        case DBGCVAR_TYPE_GC_FAR:
            switch (enmToType)
            {
                case DBGCVAR_TYPE_GC_FLAT:
                    rc = DBGFR3AddrFromSelOff(pDbgc->pUVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
                    if (RT_SUCCESS(rc))
                    {
                        pResult->enmType  = DBGCVAR_TYPE_GC_FLAT;
                        pResult->u.GCFlat = Address.FlatPtr;
                        return VINF_SUCCESS;
                    }
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_GC_FAR:
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_GC_PHYS:
                    rc = DBGFR3AddrFromSelOff(pDbgc->pUVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
                    if (RT_SUCCESS(rc))
                    {
                        pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
                        rc = DBGFR3AddrToPhys(pDbgc->pUVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
                        if (RT_SUCCESS(rc))
                            return VINF_SUCCESS;
                    }
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_HC_FLAT:
                    rc = DBGFR3AddrFromSelOff(pDbgc->pUVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
                    if (RT_SUCCESS(rc))
                    {
                        pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
                        rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pUVM, pDbgc->idCpu, &Address,
                                                       false /*fReadOnly*/, &pResult->u.pvHCFlat);
                        if (RT_SUCCESS(rc))
                            return VINF_SUCCESS;
                    }
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_HC_PHYS:
                    rc = DBGFR3AddrFromSelOff(pDbgc->pUVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
                    if (RT_SUCCESS(rc))
                    {
                        pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
                        rc = DBGFR3AddrToHostPhys(pDbgc->pUVM, pDbgc->idCpu, &Address, &pResult->u.GCPhys);
                        if (RT_SUCCESS(rc))
                            return VINF_SUCCESS;
                    }
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_NUMBER:
                    pResult->enmType     = enmToType;
                    pResult->u.u64Number = InVar.u.GCFar.off;
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_STRING:
                case DBGCVAR_TYPE_SYMBOL:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_UNKNOWN:
                case DBGCVAR_TYPE_ANY:
                    break;
            }
            break;

        case DBGCVAR_TYPE_GC_PHYS:
            switch (enmToType)
            {
                case DBGCVAR_TYPE_GC_FLAT:
                    //rc = MMR3PhysGCPhys2GCVirtEx(pDbgc->pVM, pResult->u.GCPhys, ..., &pResult->u.GCFlat); - yea, sure.
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_GC_FAR:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_GC_PHYS:
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_HC_FLAT:
                    pResult->enmType = DBGCVAR_TYPE_HC_FLAT;
                    rc = DBGFR3AddrToVolatileR3Ptr(pDbgc->pUVM, pDbgc->idCpu,
                                                   DBGFR3AddrFromPhys(pDbgc->pUVM, &Address, pArg->u.GCPhys),
                                                   false /*fReadOnly */,
                                                   &pResult->u.pvHCFlat);
                    if (RT_SUCCESS(rc))
                        return VINF_SUCCESS;
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_HC_PHYS:
                    pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
                    rc = DBGFR3AddrToHostPhys(pDbgc->pUVM, pDbgc->idCpu,
                                              DBGFR3AddrFromPhys(pDbgc->pUVM, &Address, pArg->u.GCPhys),
                                              &pResult->u.HCPhys);
                    if (RT_SUCCESS(rc))
                        return VINF_SUCCESS;
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_NUMBER:
                    pResult->enmType     = enmToType;
                    pResult->u.u64Number = InVar.u.GCPhys;
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_STRING:
                case DBGCVAR_TYPE_SYMBOL:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_UNKNOWN:
                case DBGCVAR_TYPE_ANY:
                    break;
            }
            break;

        case DBGCVAR_TYPE_HC_FLAT:
            switch (enmToType)
            {
                case DBGCVAR_TYPE_GC_FLAT:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_GC_FAR:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_GC_PHYS:
                    pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
                    rc = PGMR3DbgR3Ptr2GCPhys(pDbgc->pUVM, pArg->u.pvHCFlat, &pResult->u.GCPhys);
                    if (RT_SUCCESS(rc))
                        return VINF_SUCCESS;
                    /** @todo more memory types! */
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_HC_FLAT:
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_HC_PHYS:
                    pResult->enmType = DBGCVAR_TYPE_HC_PHYS;
                    rc = PGMR3DbgR3Ptr2HCPhys(pDbgc->pUVM, pArg->u.pvHCFlat, &pResult->u.HCPhys);
                    if (RT_SUCCESS(rc))
                        return VINF_SUCCESS;
                    /** @todo more memory types! */
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_NUMBER:
                    pResult->enmType     = enmToType;
                    pResult->u.u64Number = (uintptr_t)InVar.u.pvHCFlat;
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_STRING:
                case DBGCVAR_TYPE_SYMBOL:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_UNKNOWN:
                case DBGCVAR_TYPE_ANY:
                    break;
            }
            break;

        case DBGCVAR_TYPE_HC_PHYS:
            switch (enmToType)
            {
                case DBGCVAR_TYPE_GC_FLAT:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_GC_FAR:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_GC_PHYS:
                    pResult->enmType = DBGCVAR_TYPE_GC_PHYS;
                    rc = PGMR3DbgHCPhys2GCPhys(pDbgc->pUVM, pArg->u.HCPhys, &pResult->u.GCPhys);
                    if (RT_SUCCESS(rc))
                        return VINF_SUCCESS;
                    return VERR_DBGC_PARSE_CONVERSION_FAILED;

                case DBGCVAR_TYPE_HC_FLAT:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_HC_PHYS:
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_NUMBER:
                    pResult->enmType     = enmToType;
                    pResult->u.u64Number = InVar.u.HCPhys;
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_STRING:
                case DBGCVAR_TYPE_SYMBOL:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_UNKNOWN:
                case DBGCVAR_TYPE_ANY:
                    break;
            }
            break;

        case DBGCVAR_TYPE_NUMBER:
            switch (enmToType)
            {
                case DBGCVAR_TYPE_GC_FLAT:
                    pResult->enmType  = DBGCVAR_TYPE_GC_FLAT;
                    pResult->u.GCFlat = (RTGCPTR)InVar.u.u64Number;
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_GC_FAR:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_GC_PHYS:
                    pResult->enmType  = DBGCVAR_TYPE_GC_PHYS;
                    pResult->u.GCPhys = (RTGCPHYS)InVar.u.u64Number;
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_HC_FLAT:
                    pResult->enmType    = DBGCVAR_TYPE_HC_FLAT;
                    pResult->u.pvHCFlat = (void *)(uintptr_t)InVar.u.u64Number;
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_HC_PHYS:
                    pResult->enmType  = DBGCVAR_TYPE_HC_PHYS;
                    pResult->u.HCPhys = (RTHCPHYS)InVar.u.u64Number;
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_NUMBER:
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_STRING:
                case DBGCVAR_TYPE_SYMBOL:
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_UNKNOWN:
                case DBGCVAR_TYPE_ANY:
                    break;
            }
            break;

        case DBGCVAR_TYPE_SYMBOL:
        case DBGCVAR_TYPE_STRING:
            switch (enmToType)
            {
                case DBGCVAR_TYPE_GC_FLAT:
                case DBGCVAR_TYPE_GC_FAR:
                case DBGCVAR_TYPE_GC_PHYS:
                case DBGCVAR_TYPE_HC_FLAT:
                case DBGCVAR_TYPE_HC_PHYS:
                case DBGCVAR_TYPE_NUMBER:
                    if (fConvSyms)
                    {
                        rc = dbgcSymbolGet(pDbgc, InVar.u.pszString, enmToType, pResult);
                        if (RT_SUCCESS(rc))
                            return VINF_SUCCESS;
                    }
                    return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE;

                case DBGCVAR_TYPE_STRING:
                case DBGCVAR_TYPE_SYMBOL:
                    pResult->enmType = enmToType;
                    return VINF_SUCCESS;

                case DBGCVAR_TYPE_UNKNOWN:
                case DBGCVAR_TYPE_ANY:
                    break;
            }
            break;

        case DBGCVAR_TYPE_UNKNOWN:
        case DBGCVAR_TYPE_ANY:
            break;
    }

    AssertMsgFailed(("f=%d t=%d\n", InVar.enmType, enmToType));
    return VERR_INVALID_PARAMETER;
}
Пример #5
0
/**
 * Subtraction operator (binary).
 *
 * @returns VINF_SUCCESS on success.
 * @returns VBox evaluation / parsing error code on failure.
 *          The caller does the bitching.
 * @param   pDbgc       Debugger console instance data.
 * @param   pArg1       The first argument.
 * @param   pArg2       The 2nd argument.
 * @param   pResult     Where to store the result.
 */
static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
    LogFlow(("dbgcOpSub\n"));

    /*
     * An subtraction operation will return the left side type in the expression.
     * However, if the left hand side is a number and the right hand a pointer of
     * some kind we'll convert the left hand side to the same type as the right hand.
     * Any symbols will be resolved, strings will be rejected.
     */
    DBGCVAR     Sym1, Sym2;
    if (    pArg2->enmType == DBGCVAR_TYPE_SYMBOL
        &&  (   pArg1->enmType == DBGCVAR_TYPE_NUMBER
             || pArg1->enmType == DBGCVAR_TYPE_SYMBOL))
    {
        int rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_ANY, &Sym2);
        if (RT_FAILURE(rc))
            return rc;
        pArg2 = &Sym2;
    }

    if (   pArg1->enmType == DBGCVAR_TYPE_STRING
        || pArg2->enmType == DBGCVAR_TYPE_STRING)
        return VERR_DBGC_PARSE_INVALID_OPERATION;

    if (pArg1->enmType == DBGCVAR_TYPE_SYMBOL)
    {
        DBGCVARTYPE enmType;
        switch (pArg2->enmType)
        {
            case DBGCVAR_TYPE_NUMBER:
                enmType = DBGCVAR_TYPE_ANY;
                break;
            case DBGCVAR_TYPE_GC_FLAT:
            case DBGCVAR_TYPE_GC_PHYS:
            case DBGCVAR_TYPE_HC_FLAT:
            case DBGCVAR_TYPE_HC_PHYS:
                enmType = pArg2->enmType;
                break;
            case DBGCVAR_TYPE_GC_FAR:
                enmType = DBGCVAR_TYPE_GC_FLAT;
                break;
            default: AssertFailedReturn(VERR_DBGC_IPE);
        }
        if (enmType != DBGCVAR_TYPE_STRING)
        {
            int rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_ANY, &Sym1);
            if (RT_FAILURE(rc))
                return rc;
            pArg1 = &Sym1;
        }
    }
    else if (pArg1->enmType == DBGCVAR_TYPE_NUMBER)
    {
        PFNDBGCOPUNARY pOp = NULL;
        switch (pArg2->enmType)
        {
            case DBGCVAR_TYPE_GC_FAR:
            case DBGCVAR_TYPE_GC_FLAT:
                pOp = dbgcOpAddrFlat;
                break;
            case DBGCVAR_TYPE_GC_PHYS:
                pOp = dbgcOpAddrPhys;
                break;
            case DBGCVAR_TYPE_HC_FLAT:
                pOp = dbgcOpAddrHost;
                break;
            case DBGCVAR_TYPE_HC_PHYS:
                pOp = dbgcOpAddrHostPhys;
                break;
            case DBGCVAR_TYPE_NUMBER:
                break;
            default: AssertFailedReturn(VERR_DBGC_IPE);
        }
        if (pOp)
        {
            int rc = pOp(pDbgc, pArg1, DBGCVAR_CAT_ANY, &Sym1);
            if (RT_FAILURE(rc))
                return rc;
            pArg1 = &Sym1;
        }
    }

    /*
     * Normal processing.
     */
    int         rc;
    DBGCVAR     Var;
    DBGCVAR     Var2;
    switch (pArg1->enmType)
    {
        /*
         * GC Flat
         */
        case DBGCVAR_TYPE_GC_FLAT:
            switch (pArg2->enmType)
            {
                case DBGCVAR_TYPE_HC_FLAT:
                case DBGCVAR_TYPE_HC_PHYS:
                    return VERR_DBGC_PARSE_INVALID_OPERATION;
                default:
                    *pResult = *pArg1;
                    rc = dbgcOpAddrFlat(pDbgc, pArg2, DBGCVAR_CAT_ANY, &Var);
                    if (RT_FAILURE(rc))
                        return rc;
                    pResult->u.GCFlat -= pArg2->u.GCFlat;
                    break;
            }
            break;

        /*
         * GC Far
         */
        case DBGCVAR_TYPE_GC_FAR:
            switch (pArg2->enmType)
            {
                case DBGCVAR_TYPE_HC_FLAT:
                case DBGCVAR_TYPE_HC_PHYS:
                    return VERR_DBGC_PARSE_INVALID_OPERATION;
                case DBGCVAR_TYPE_NUMBER:
                    *pResult = *pArg1;
                    pResult->u.GCFar.off -= (RTGCPTR)pArg2->u.u64Number;
                    break;
                default:
                    rc = dbgcOpAddrFlat(pDbgc, pArg1, DBGCVAR_CAT_ANY, pResult);
                    if (RT_FAILURE(rc))
                        return rc;
                    rc = dbgcOpAddrFlat(pDbgc, pArg2, DBGCVAR_CAT_ANY, &Var);
                    if (RT_FAILURE(rc))
                        return rc;
                    pResult->u.GCFlat -= pArg2->u.GCFlat;
                    break;
            }
            break;

        /*
         * GC Phys
         */
        case DBGCVAR_TYPE_GC_PHYS:
            switch (pArg2->enmType)
            {
                case DBGCVAR_TYPE_HC_FLAT:
                case DBGCVAR_TYPE_HC_PHYS:
                    return VERR_DBGC_PARSE_INVALID_OPERATION;
                default:
                    *pResult = *pArg1;
                    rc = dbgcOpAddrPhys(pDbgc, pArg2, DBGCVAR_CAT_ANY, &Var);
                    if (RT_FAILURE(rc))
                        return rc;
                    if (Var.enmType != DBGCVAR_TYPE_GC_PHYS)
                        return VERR_DBGC_PARSE_INVALID_OPERATION;
                    pResult->u.GCPhys -= Var.u.GCPhys;
                    break;
            }
            break;

        /*
         * HC Flat
         */
        case DBGCVAR_TYPE_HC_FLAT:
            *pResult = *pArg1;
            rc = dbgcOpAddrHost(pDbgc, pArg2, DBGCVAR_CAT_ANY, &Var2);
            if (RT_FAILURE(rc))
                return rc;
            rc = dbgcOpAddrFlat(pDbgc, &Var2, DBGCVAR_CAT_ANY, &Var);
            if (RT_FAILURE(rc))
                return rc;
            pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat - (uintptr_t)Var.u.pvHCFlat;
            break;

        /*
         * HC Phys
         */
        case DBGCVAR_TYPE_HC_PHYS:
            *pResult = *pArg1;
            rc = dbgcOpAddrHostPhys(pDbgc, pArg2, DBGCVAR_CAT_ANY, &Var);
            if (RT_FAILURE(rc))
                return rc;
            pResult->u.HCPhys -= Var.u.HCPhys;
            break;

        /*
         * Numbers (see start of function)
         */
        case DBGCVAR_TYPE_NUMBER:
            *pResult = *pArg1;
            switch (pArg2->enmType)
            {
                case DBGCVAR_TYPE_SYMBOL:
                    rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
                    if (RT_FAILURE(rc))
                        return rc;
                case DBGCVAR_TYPE_NUMBER:
                    pResult->u.u64Number -= pArg2->u.u64Number;
                    break;
                default:
                    return VERR_DBGC_PARSE_INVALID_OPERATION;
            }
            break;

        default:
            return VERR_DBGC_PARSE_INVALID_OPERATION;

    }
    return VINF_SUCCESS;
}
Пример #6
0
/**
 * Addition operator (binary).
 *
 * @returns VINF_SUCCESS on success.
 * @returns VBox evaluation / parsing error code on failure.
 *          The caller does the bitching.
 * @param   pDbgc       Debugger console instance data.
 * @param   pArg1       The first argument.
 * @param   pArg2       The 2nd argument.
 * @param   pResult     Where to store the result.
 */
static DECLCALLBACK(int) dbgcOpAdd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
    LogFlow(("dbgcOpAdd\n"));

    /*
     * An addition operation will return (when possible) the left side type in the
     * expression. We make an omission for numbers, where we'll take the right side
     * type instead. An expression where only the left hand side is a symbol we'll
     * use the right hand type to try resolve it.
     */
    if (   pArg1->enmType == DBGCVAR_TYPE_STRING
        || pArg2->enmType == DBGCVAR_TYPE_STRING)
        return VERR_DBGC_PARSE_INVALID_OPERATION; /** @todo string contactenation later. */

    if (    (pArg1->enmType == DBGCVAR_TYPE_NUMBER && pArg2->enmType != DBGCVAR_TYPE_SYMBOL)
        ||  (pArg1->enmType == DBGCVAR_TYPE_SYMBOL && pArg2->enmType != DBGCVAR_TYPE_SYMBOL))
    {
        PCDBGCVAR pTmp = pArg2;
        pArg2 = pArg1;
        pArg1 = pTmp;
    }

    DBGCVAR     Sym1, Sym2;
    if (pArg1->enmType == DBGCVAR_TYPE_SYMBOL)
    {
        int rc = dbgcSymbolGet(pDbgc, pArg1->u.pszString, DBGCVAR_TYPE_ANY, &Sym1);
        if (RT_FAILURE(rc))
            return rc;
        pArg1 = &Sym1;

        rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_ANY, &Sym2);
        if (RT_FAILURE(rc))
            return rc;
        pArg2 = &Sym2;
    }

    int         rc;
    DBGCVAR     Var;
    DBGCVAR     Var2;
    switch (pArg1->enmType)
    {
        /*
         * GC Flat
         */
        case DBGCVAR_TYPE_GC_FLAT:
            switch (pArg2->enmType)
            {
                case DBGCVAR_TYPE_HC_FLAT:
                case DBGCVAR_TYPE_HC_PHYS:
                    return VERR_DBGC_PARSE_INVALID_OPERATION;
                default:
                    *pResult = *pArg1;
                    rc = dbgcOpAddrFlat(pDbgc, pArg2, DBGCVAR_CAT_ANY, &Var);
                    if (RT_FAILURE(rc))
                        return rc;
                    pResult->u.GCFlat += pArg2->u.GCFlat;
                    break;
            }
            break;

        /*
         * GC Far
         */
        case DBGCVAR_TYPE_GC_FAR:
            switch (pArg2->enmType)
            {
                case DBGCVAR_TYPE_HC_FLAT:
                case DBGCVAR_TYPE_HC_PHYS:
                    return VERR_DBGC_PARSE_INVALID_OPERATION;
                case DBGCVAR_TYPE_NUMBER:
                    *pResult = *pArg1;
                    pResult->u.GCFar.off += (RTGCPTR)pArg2->u.u64Number;
                    break;
                default:
                    rc = dbgcOpAddrFlat(pDbgc, pArg1, DBGCVAR_CAT_ANY, pResult);
                    if (RT_FAILURE(rc))
                        return rc;
                    rc = dbgcOpAddrFlat(pDbgc, pArg2, DBGCVAR_CAT_ANY, &Var);
                    if (RT_FAILURE(rc))
                        return rc;
                    pResult->u.GCFlat += pArg2->u.GCFlat;
                    break;
            }
            break;

        /*
         * GC Phys
         */
        case DBGCVAR_TYPE_GC_PHYS:
            switch (pArg2->enmType)
            {
                case DBGCVAR_TYPE_HC_FLAT:
                case DBGCVAR_TYPE_HC_PHYS:
                    return VERR_DBGC_PARSE_INVALID_OPERATION;
                default:
                    *pResult = *pArg1;
                    rc = dbgcOpAddrPhys(pDbgc, pArg2, DBGCVAR_CAT_ANY, &Var);
                    if (RT_FAILURE(rc))
                        return rc;
                    if (Var.enmType != DBGCVAR_TYPE_GC_PHYS)
                        return VERR_DBGC_PARSE_INVALID_OPERATION;
                    pResult->u.GCPhys += Var.u.GCPhys;
                    break;
            }
            break;

        /*
         * HC Flat
         */
        case DBGCVAR_TYPE_HC_FLAT:
            *pResult = *pArg1;
            rc = dbgcOpAddrHost(pDbgc, pArg2, DBGCVAR_CAT_ANY, &Var2);
            if (RT_FAILURE(rc))
                return rc;
            rc = dbgcOpAddrFlat(pDbgc, &Var2, DBGCVAR_CAT_ANY, &Var);
            if (RT_FAILURE(rc))
                return rc;
            pResult->u.pvHCFlat = (char *)pResult->u.pvHCFlat + (uintptr_t)Var.u.pvHCFlat;
            break;

        /*
         * HC Phys
         */
        case DBGCVAR_TYPE_HC_PHYS:
            *pResult = *pArg1;
            rc = dbgcOpAddrHostPhys(pDbgc, pArg2, DBGCVAR_CAT_ANY, &Var);
            if (RT_FAILURE(rc))
                return rc;
            pResult->u.HCPhys += Var.u.HCPhys;
            break;

        /*
         * Numbers (see start of function)
         */
        case DBGCVAR_TYPE_NUMBER:
            *pResult = *pArg1;
            switch (pArg2->enmType)
            {
                case DBGCVAR_TYPE_SYMBOL:
                    rc = dbgcSymbolGet(pDbgc, pArg2->u.pszString, DBGCVAR_TYPE_NUMBER, &Var);
                    if (RT_FAILURE(rc))
                        return rc;
                case DBGCVAR_TYPE_NUMBER:
                    pResult->u.u64Number += pArg2->u.u64Number;
                    break;
                default:
                    return VERR_DBGC_PARSE_INVALID_OPERATION;
            }
            break;

        default:
            return VERR_DBGC_PARSE_INVALID_OPERATION;

    }
    return VINF_SUCCESS;
}