DBGCOps.cpp revision dec9772aebc272b06ae34a7f3da31f3e716eb1dc
/* $Id$ */
/** @file
* DBGC - Debugger Console, Operators.
*/
/*
* Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DBGC
#include <stdlib.h>
#include <stdio.h>
#include "DBGCInternal.h"
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpMult(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpDiv(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpMod(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpAdd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpSub(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpBitwiseShiftLeft(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpBitwiseShiftRight(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpBitwiseAnd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpBitwiseXor(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpBitwiseOr(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpBooleanAnd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpBooleanOr(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpRangeLength(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpRangeLengthBytes(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
static DECLCALLBACK(int) dbgcOpRangeTo(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult);
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
/**
* Generic implementation of a binary operator.
*
* @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.
* @param Operator The C operator.
* @param fIsDiv Set if it's division and we need to check for zero on the
* right hand side.
*/
do \
{ \
/* Get the 64-bit right side value. */ \
else if (RT_SUCCESS(rc)) \
{ \
/* Apply it to the left hand side. */ \
{ \
if (RT_FAILURE(rc)) \
return rc; \
} \
else \
{ \
case DBGCVAR_TYPE_GC_FLAT: \
break; \
case DBGCVAR_TYPE_GC_FAR: \
break; \
case DBGCVAR_TYPE_GC_PHYS: \
break; \
case DBGCVAR_TYPE_HC_FLAT: \
break; \
case DBGCVAR_TYPE_HC_FAR: \
break; \
case DBGCVAR_TYPE_HC_PHYS: \
break; \
case DBGCVAR_TYPE_NUMBER: \
break; \
default: \
return VERR_PARSE_INCORRECT_ARG_TYPE; \
} \
} \
return rc; \
} while (0)
/**
* Far pointers are considered more important that physical and flat pointers.
*
* @param pArg1 The left side argument. Input & output.
* @param pArg2 The right side argument. Input & output.
*/
do \
{ \
{ \
} \
} while (0)
/*******************************************************************************
* Global Variables *
*******************************************************************************/
/** Operators. */
{
/* szName is initialized as a 4 char array because of M$C elsewise optimizing it away in /Ox mode (the 'const char' vs 'char' problem). */
/* szName, cchName, fBinary, iPrecedence, pfnHandlerUnary, pfnHandlerBitwise */
};
/** Number of operators in the operator array. */
/**
* 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.
*/
{
{
case DBGCVAR_TYPE_GC_FLAT:
break;
case DBGCVAR_TYPE_GC_FAR:
break;
case DBGCVAR_TYPE_GC_PHYS:
break;
case DBGCVAR_TYPE_HC_FLAT:
break;
case DBGCVAR_TYPE_HC_FAR:
break;
case DBGCVAR_TYPE_HC_PHYS:
break;
case DBGCVAR_TYPE_STRING:
case DBGCVAR_TYPE_SYMBOL:
{
if (RT_FAILURE(rc))
return rc;
/* fall thru */
}
case DBGCVAR_TYPE_NUMBER:
break;
default:
return VERR_PARSE_INCORRECT_ARG_TYPE;
}
return VINF_SUCCESS;
}
/**
* Minus (unary).
*
* @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 pArg The argument.
* @param pResult Where to store the result.
*/
{
LogFlow(("dbgcOpMinus\n"));
{
case DBGCVAR_TYPE_GC_FLAT:
break;
case DBGCVAR_TYPE_GC_FAR:
break;
case DBGCVAR_TYPE_GC_PHYS:
break;
case DBGCVAR_TYPE_HC_FLAT:
break;
case DBGCVAR_TYPE_HC_FAR:
break;
case DBGCVAR_TYPE_HC_PHYS:
break;
case DBGCVAR_TYPE_NUMBER:
break;
case DBGCVAR_TYPE_UNKNOWN:
case DBGCVAR_TYPE_STRING:
default:
return VERR_PARSE_INCORRECT_ARG_TYPE;
}
return VINF_SUCCESS;
}
/**
* Plus (unary).
*
* @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 pArg The argument.
* @param pResult Where to store the result.
*/
{
LogFlow(("dbgcOpPluss\n"));
{
case DBGCVAR_TYPE_GC_FLAT:
case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_GC_PHYS:
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
case DBGCVAR_TYPE_NUMBER:
break;
case DBGCVAR_TYPE_UNKNOWN:
case DBGCVAR_TYPE_STRING:
default:
return VERR_PARSE_INCORRECT_ARG_TYPE;
}
return VINF_SUCCESS;
}
/**
* Boolean not (unary).
*
* @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 pArg The argument.
* @param pResult Where to store the result.
*/
{
LogFlow(("dbgcOpBooleanNot\n"));
{
case DBGCVAR_TYPE_GC_FLAT:
break;
case DBGCVAR_TYPE_GC_FAR:
break;
case DBGCVAR_TYPE_GC_PHYS:
break;
case DBGCVAR_TYPE_HC_FLAT:
break;
case DBGCVAR_TYPE_HC_FAR:
break;
case DBGCVAR_TYPE_HC_PHYS:
break;
case DBGCVAR_TYPE_NUMBER:
break;
case DBGCVAR_TYPE_STRING:
break;
case DBGCVAR_TYPE_UNKNOWN:
default:
return VERR_PARSE_INCORRECT_ARG_TYPE;
}
return VINF_SUCCESS;
}
/**
* Bitwise not (unary).
*
* @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 pArg The argument.
* @param pResult Where to store the result.
*/
{
LogFlow(("dbgcOpBitwiseNot\n"));
{
case DBGCVAR_TYPE_GC_FLAT:
break;
case DBGCVAR_TYPE_GC_FAR:
break;
case DBGCVAR_TYPE_GC_PHYS:
break;
case DBGCVAR_TYPE_HC_FLAT:
break;
case DBGCVAR_TYPE_HC_FAR:
break;
case DBGCVAR_TYPE_HC_PHYS:
break;
case DBGCVAR_TYPE_NUMBER:
break;
case DBGCVAR_TYPE_UNKNOWN:
case DBGCVAR_TYPE_STRING:
default:
return VERR_PARSE_INCORRECT_ARG_TYPE;
}
return VINF_SUCCESS;
}
/**
* Reference variable (unary).
*
* @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 pArg The argument.
* @param pResult Where to store the result.
*/
{
/*
* Parse sanity.
*/
return VERR_PARSE_INCORRECT_ARG_TYPE;
/*
* Lookup the variable.
*/
{
{
return VINF_SUCCESS;
}
}
return VERR_PARSE_VARIABLE_NOT_FOUND;
}
/**
* Reference register (unary).
*
* @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 pArg The argument.
* @param pResult Where to store the result.
*/
{
/*
* Parse sanity.
*/
return VERR_PARSE_INCORRECT_ARG_TYPE;
/*
* Get the register.
*/
if (RT_SUCCESS(rc))
{
switch (enmType)
{
case DBGFREGVALTYPE_U8:
return VINF_SUCCESS;
case DBGFREGVALTYPE_U16:
return VINF_SUCCESS;
case DBGFREGVALTYPE_U32:
return VINF_SUCCESS;
case DBGFREGVALTYPE_U64:
return VINF_SUCCESS;
case DBGFREGVALTYPE_U128:
return VINF_SUCCESS;
case DBGFREGVALTYPE_R80:
#else
#endif
return VINF_SUCCESS;
case DBGFREGVALTYPE_DTR:
return VINF_SUCCESS;
case DBGFREGVALTYPE_INVALID:
case DBGFREGVALTYPE_END:
break;
}
}
return rc;
}
/**
* Flat address (unary).
*
* @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 pArg The argument.
* @param pResult Where to store the result.
*/
{
LogFlow(("dbgcOpAddrFlat\n"));
int rc;
{
case DBGCVAR_TYPE_GC_FLAT:
return VINF_SUCCESS;
case DBGCVAR_TYPE_GC_FAR:
{
rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
if (RT_SUCCESS(rc))
{
return VINF_SUCCESS;
}
return VERR_PARSE_CONVERSION_FAILED;
}
case DBGCVAR_TYPE_GC_PHYS:
//rc = MMR3PhysGCPhys2GCVirtEx(pDbgc->pVM, pResult->u.GCPhys, ..., &pResult->u.GCFlat); - yea, sure.
return VERR_PARSE_INCORRECT_ARG_TYPE;
case DBGCVAR_TYPE_HC_FLAT:
return VINF_SUCCESS;
case DBGCVAR_TYPE_HC_FAR:
return VERR_PARSE_INCORRECT_ARG_TYPE;
case DBGCVAR_TYPE_HC_PHYS:
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
return VERR_PARSE_CONVERSION_FAILED;
case DBGCVAR_TYPE_NUMBER:
return VINF_SUCCESS;
case DBGCVAR_TYPE_STRING:
case DBGCVAR_TYPE_UNKNOWN:
default:
return VERR_PARSE_INCORRECT_ARG_TYPE;
}
}
/**
* Physical address (unary).
*
* @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 pArg The argument.
* @param pResult Where to store the result.
*/
{
LogFlow(("dbgcOpAddrPhys\n"));
int rc;
{
case DBGCVAR_TYPE_GC_FLAT:
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
return VERR_PARSE_CONVERSION_FAILED;
case DBGCVAR_TYPE_GC_FAR:
rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
}
return VERR_PARSE_CONVERSION_FAILED;
case DBGCVAR_TYPE_GC_PHYS:
return VINF_SUCCESS;
case DBGCVAR_TYPE_HC_FLAT:
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
/** @todo more memory types! */
return VERR_PARSE_CONVERSION_FAILED;
case DBGCVAR_TYPE_HC_FAR:
return VERR_PARSE_INCORRECT_ARG_TYPE;
case DBGCVAR_TYPE_HC_PHYS:
return VINF_SUCCESS;
case DBGCVAR_TYPE_NUMBER:
return VINF_SUCCESS;
case DBGCVAR_TYPE_STRING:
case DBGCVAR_TYPE_UNKNOWN:
default:
return VERR_PARSE_INCORRECT_ARG_TYPE;
}
return VINF_SUCCESS;
}
/**
* Physical host address (unary).
*
* @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 pArg The argument.
* @param pResult Where to store the result.
*/
{
LogFlow(("dbgcOpAddrPhys\n"));
int rc;
{
case DBGCVAR_TYPE_GC_FLAT:
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
return VERR_PARSE_CONVERSION_FAILED;
case DBGCVAR_TYPE_GC_FAR:
{
rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
}
return VERR_PARSE_CONVERSION_FAILED;
}
case DBGCVAR_TYPE_GC_PHYS:
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
return VERR_PARSE_CONVERSION_FAILED;
case DBGCVAR_TYPE_HC_FLAT:
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
/** @todo more memory types! */
return VERR_PARSE_CONVERSION_FAILED;
case DBGCVAR_TYPE_HC_FAR:
return VERR_PARSE_INCORRECT_ARG_TYPE;
case DBGCVAR_TYPE_HC_PHYS:
return VINF_SUCCESS;
case DBGCVAR_TYPE_NUMBER:
return VINF_SUCCESS;
case DBGCVAR_TYPE_STRING:
case DBGCVAR_TYPE_UNKNOWN:
default:
return VERR_PARSE_INCORRECT_ARG_TYPE;
}
return VINF_SUCCESS;
}
/**
* Host address (unary).
*
* @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 pArg The argument.
* @param pResult Where to store the result.
*/
{
LogFlow(("dbgcOpAddrHost\n"));
int rc;
{
case DBGCVAR_TYPE_GC_FLAT:
false /*fReadOnly */,
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
return VERR_PARSE_CONVERSION_FAILED;
case DBGCVAR_TYPE_GC_FAR:
rc = DBGFR3AddrFromSelOff(pDbgc->pVM, pDbgc->idCpu, &Address, pArg->u.GCFar.sel, pArg->u.GCFar.off);
if (RT_SUCCESS(rc))
{
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
}
return VERR_PARSE_CONVERSION_FAILED;
case DBGCVAR_TYPE_GC_PHYS:
false /*fReadOnly */,
if (RT_SUCCESS(rc))
return VINF_SUCCESS;
return VERR_PARSE_CONVERSION_FAILED;
case DBGCVAR_TYPE_HC_FLAT:
return VINF_SUCCESS;
case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
/** @todo !*/
return VERR_PARSE_CONVERSION_FAILED;
case DBGCVAR_TYPE_NUMBER:
return VINF_SUCCESS;
case DBGCVAR_TYPE_STRING:
case DBGCVAR_TYPE_UNKNOWN:
default:
return VERR_PARSE_INCORRECT_ARG_TYPE;
}
}
/**
* Bitwise not (unary).
*
* @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 pArg The argument.
* @param pResult Where to store the result.
*/
static DECLCALLBACK(int) dbgcOpAddrFar(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
LogFlow(("dbgcOpAddrFar\n"));
int rc;
{
case DBGCVAR_TYPE_STRING:
if (RT_FAILURE(rc))
return rc;
break;
case DBGCVAR_TYPE_NUMBER:
break;
case DBGCVAR_TYPE_GC_FLAT:
case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_GC_PHYS:
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
case DBGCVAR_TYPE_UNKNOWN:
default:
return VERR_PARSE_INCORRECT_ARG_TYPE;
}
/* common code for the two types we support. */
{
case DBGCVAR_TYPE_GC_FLAT:
break;
case DBGCVAR_TYPE_HC_FLAT:
break;
case DBGCVAR_TYPE_NUMBER:
break;
case DBGCVAR_TYPE_STRING:
{
if (RT_FAILURE(rc))
return rc;
break;
}
case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_GC_PHYS:
case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
case DBGCVAR_TYPE_UNKNOWN:
default:
return VERR_PARSE_INCORRECT_ARG_TYPE;
}
return VINF_SUCCESS;
}
/**
* Multiplication 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) dbgcOpMult(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
LogFlow(("dbgcOpMult\n"));
}
/**
* Division 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.
*/
{
LogFlow(("dbgcOpDiv\n"));
}
/**
* Modulus 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.
*/
{
LogFlow(("dbgcOpMod\n"));
}
/**
* 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.
*/
{
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 string we'll
* use the right hand type assuming that the string is a symbol.
*/
{
}
{
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
}
int rc;
{
/*
* GC Flat
*/
case DBGCVAR_TYPE_GC_FLAT:
{
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
default:
if (RT_FAILURE(rc))
return rc;
break;
}
break;
/*
* GC Far
*/
case DBGCVAR_TYPE_GC_FAR:
{
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
case DBGCVAR_TYPE_NUMBER:
break;
default:
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
break;
}
break;
/*
* GC Phys
*/
case DBGCVAR_TYPE_GC_PHYS:
{
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
default:
if (RT_FAILURE(rc))
return rc;
return VERR_PARSE_INVALID_OPERATION;
break;
}
break;
/*
* HC Flat
*/
case DBGCVAR_TYPE_HC_FLAT:
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
break;
/*
* HC Far
*/
case DBGCVAR_TYPE_HC_FAR:
{
case DBGCVAR_TYPE_NUMBER:
break;
default:
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
break;
}
break;
/*
* HC Phys
*/
case DBGCVAR_TYPE_HC_PHYS:
if (RT_FAILURE(rc))
return rc;
break;
/*
* Numbers (see start of function)
*/
case DBGCVAR_TYPE_NUMBER:
{
case DBGCVAR_TYPE_SYMBOL:
case DBGCVAR_TYPE_STRING:
if (RT_FAILURE(rc))
return rc;
case DBGCVAR_TYPE_NUMBER:
break;
default:
return VERR_PARSE_INVALID_OPERATION;
}
break;
default:
return VERR_PARSE_INVALID_OPERATION;
}
return VINF_SUCCESS;
}
/**
* 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.
*/
{
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 strings will be attempted resolved as symbols.
*/
{
if (RT_FAILURE(rc))
return rc;
}
{
{
case DBGCVAR_TYPE_NUMBER:
break;
case DBGCVAR_TYPE_GC_FLAT:
case DBGCVAR_TYPE_GC_PHYS:
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_PHYS:
break;
case DBGCVAR_TYPE_GC_FAR:
break;
case DBGCVAR_TYPE_HC_FAR:
break;
default:
case DBGCVAR_TYPE_STRING:
AssertMsgFailed(("Can't happen\n"));
break;
}
if (enmType != DBGCVAR_TYPE_STRING)
{
if (RT_FAILURE(rc))
return rc;
}
}
{
{
case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_GC_FLAT:
break;
case DBGCVAR_TYPE_GC_PHYS:
break;
case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_FLAT:
break;
case DBGCVAR_TYPE_HC_PHYS:
break;
case DBGCVAR_TYPE_NUMBER:
break;
default:
case DBGCVAR_TYPE_STRING:
AssertMsgFailed(("Can't happen\n"));
break;
}
if (pOp)
{
if (RT_FAILURE(rc))
return rc;
}
}
/*
* Normal processing.
*/
int rc;
{
/*
* GC Flat
*/
case DBGCVAR_TYPE_GC_FLAT:
{
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
default:
if (RT_FAILURE(rc))
return rc;
break;
}
break;
/*
* GC Far
*/
case DBGCVAR_TYPE_GC_FAR:
{
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
case DBGCVAR_TYPE_NUMBER:
break;
default:
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
break;
}
break;
/*
* GC Phys
*/
case DBGCVAR_TYPE_GC_PHYS:
{
case DBGCVAR_TYPE_HC_FLAT:
case DBGCVAR_TYPE_HC_FAR:
case DBGCVAR_TYPE_HC_PHYS:
return VERR_PARSE_INVALID_OPERATION;
default:
if (RT_FAILURE(rc))
return rc;
return VERR_PARSE_INVALID_OPERATION;
break;
}
break;
/*
* HC Flat
*/
case DBGCVAR_TYPE_HC_FLAT:
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
break;
/*
* HC Far
*/
case DBGCVAR_TYPE_HC_FAR:
{
case DBGCVAR_TYPE_NUMBER:
break;
default:
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
if (RT_FAILURE(rc))
return rc;
break;
}
break;
/*
* HC Phys
*/
case DBGCVAR_TYPE_HC_PHYS:
if (RT_FAILURE(rc))
return rc;
break;
/*
* Numbers (see start of function)
*/
case DBGCVAR_TYPE_NUMBER:
{
case DBGCVAR_TYPE_SYMBOL:
case DBGCVAR_TYPE_STRING:
if (RT_FAILURE(rc))
return rc;
case DBGCVAR_TYPE_NUMBER:
break;
default:
return VERR_PARSE_INVALID_OPERATION;
}
break;
default:
return VERR_PARSE_INVALID_OPERATION;
}
return VINF_SUCCESS;
}
/**
* Bitwise shift left 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) dbgcOpBitwiseShiftLeft(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
LogFlow(("dbgcOpBitwiseShiftLeft\n"));
}
/**
* Bitwise shift right 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) dbgcOpBitwiseShiftRight(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
LogFlow(("dbgcOpBitwiseShiftRight\n"));
}
/**
* Bitwise and 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) dbgcOpBitwiseAnd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
LogFlow(("dbgcOpBitwiseAnd\n"));
}
/**
* Bitwise exclusive or 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) dbgcOpBitwiseXor(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
LogFlow(("dbgcOpBitwiseXor\n"));
}
/**
* Bitwise inclusive or 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) dbgcOpBitwiseOr(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
LogFlow(("dbgcOpBitwiseOr\n"));
}
/**
* Boolean and 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) dbgcOpBooleanAnd(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
LogFlow(("dbgcOpBooleanAnd\n"));
/** @todo force numeric return value? */
}
/**
* Boolean or 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) dbgcOpBooleanOr(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
LogFlow(("dbgcOpBooleanOr\n"));
/** @todo force numeric return value? */
}
/**
* 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"));
/*
* Make result. Strings needs to be resolved into symbols.
*/
{
if (RT_FAILURE(rc))
return rc;
}
else
/*
* Convert 2nd argument to element count.
*/
{
case DBGCVAR_TYPE_NUMBER:
break;
case DBGCVAR_TYPE_STRING:
{
if (RT_FAILURE(rc))
return rc;
break;
}
default:
return VERR_PARSE_INVALID_OPERATION;
}
return VINF_SUCCESS;
}
/**
* 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) dbgcOpRangeLengthBytes(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
LogFlow(("dbgcOpRangeLengthBytes\n"));
if (RT_SUCCESS(rc))
return rc;
}
/**
* 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) dbgcOpRangeTo(PDBGC pDbgc, PCDBGCVAR pArg1, PCDBGCVAR pArg2, PDBGCVAR pResult)
{
LogFlow(("dbgcOpRangeTo\n"));
/*
* Calc number of bytes between the two args.
*/
if (RT_FAILURE(rc))
return rc;
/*
* Use the diff as the range of Arg1.
*/
{
case DBGCVAR_TYPE_GC_FLAT:
break;
case DBGCVAR_TYPE_GC_PHYS:
break;
case DBGCVAR_TYPE_HC_FLAT:
break;
case DBGCVAR_TYPE_HC_PHYS:
break;
case DBGCVAR_TYPE_NUMBER:
break;
case DBGCVAR_TYPE_GC_FAR:
case DBGCVAR_TYPE_STRING:
case DBGCVAR_TYPE_HC_FAR:
default:
AssertMsgFailed(("Impossible!\n"));
return VERR_PARSE_INVALID_OPERATION;
}
return VINF_SUCCESS;
}
/**
* Searches for an operator descriptor which matches the start of
* the expression given us.
*
* @returns Pointer to the operator on success.
* @param pDbgc The debug console instance.
* @param pszExpr Pointer to the expression string which might start with an operator.
* @param fPreferBinary Whether to favour binary or unary operators.
* Caller must assert that it's the desired type! Both types will still
* be returned, this is only for resolving duplicates.
* @param chPrev The previous char. Some operators requires a blank in front of it.
*/
{
{
{
/*
* Check that we don't mistake it for some other operator which have more chars.
*/
unsigned j;
break;
if (j < RT_ELEMENTS(g_aOps))
continue; /* we'll catch it later. (for theoretical +,++,+++ cases.) */
/*
* Preferred type?
*/
break;
}
}
if (pOp)
return pOp;
}