Windows2000/private/windbg64/debugger/ee/debwalk.c
2020-09-30 17:12:32 +02:00

349 lines
9.3 KiB
C

/*** debwalk.c - walk bound expression tree and perform operations
*/
#include "debexpr.h"
bool_t PushCXT (peval_t);
bool_t GetCXTL (pnode_t);
bool_t GetCXTFunction (pnode_t, pnode_t);
/** DoGetCXTL - Gets a list of symbols and contexts for expression
* status = DoGetCXTL (phTM, phCXTL)
* Entry phTM = pointer to handle to expression state structure
* phCXTL = pointer to handle for CXT list buffer
* Exit *phCXTL = handle for CXT list buffer
* Returns EENOERROR if no error
* status code if error
*/
ulong
DoGetCXTL (
PHTM phTM,
PHCXTL phCXTL
)
{
ulong retval = EECATASTROPHIC;
// lock the expression state structure and copy the context package
DASSERT (*phTM != 0);
if (*phTM != 0) {
pExState = (pexstate_t) MemLock (*phTM);
if ((pExState->state.parse_ok == TRUE) &&
(pExState->state.bind_ok == TRUE)) {
if ((hCxtl = MemAllocate (sizeof (CXTL) + 5 * sizeof (HCS))) == 0) {
pExState->err_num = ERR_NOMEMORY;
MemUnLock (*phTM);
*phCXTL = hCxtl;
return (EEGENERAL);
} else {
pCxtl = (PCXTL) MemLock (hCxtl);
mCxtl = 5;
pCxtl->CXT = pExState->cxt;
pCxtl->cHCS = 0;
}
pTree = (pstree_t) MemLock (pExState->hETree);
if (GetCXTL ((pnode_t)((bnode_t)pTree->start_node))) {
retval = EENOERROR;
} else {
retval = EEGENERAL;
}
*phCXTL = hCxtl;
MemUnLock (hCxtl);
MemUnLock (pExState->hETree);
}
MemUnLock (*phTM);
}
return (retval);
}
/** GetCXTL - get CXT list from bound expression tree
* fSuccess = GetCXTL (pn)
* Entry pn = pointer to node
* hCxtl = handle of CXT list
* pCxtl = pointer to CXT list
* mCxtl = maximum number of context list entries
* Exit *phCXTL = handle for CXT list
* Returns TRUE if no error
* FALSEif error
*/
bool_t
GetCXTL (
pnode_t pn
)
{
PCXT oldCxt;
bool_t retval;
peval_t pv;
CXT Cxt;
// Recurse down the tree.
pv = &pn->v[0];
switch (NODE_OP (pn)) {
case OP_typestr:
return (TRUE);
case OP_const:
#pragma message ("Remove following code when 'langapi' for v3 exists")
//Cxt = *pCxt;
//memset (SHpADDRFrompCXT (pCxt), 0, sizeof (ADDR));
retval = PushCXT (pv);
//*pCxt = Cxt;
return (retval);
case OP_ident:
case OP_this:
case OP_hsym:
case OP_retval:
return (PushCXT (pv));
case OP_cast:
return (GetCXTL ((pnode_t)NODE_RCHILD (pn)));
case OP_function:
return (GetCXTFunction ((pnode_t)NODE_LCHILD (pn), (pnode_t)NODE_RCHILD (pn)));
case OP_context:
// Set the new context for evaluation of the remainder of this
// part of the tree
oldCxt = pCxt;
pCxt = SHpCXTFrompCXF ((PCXF)&pn->v[0]);
retval = GetCXTL ((pnode_t)NODE_LCHILD (pn));
pCxt = oldCxt;
return (retval);
// All other operators come through here. Recurse down the tree
default:
if (!GetCXTL ((pnode_t)NODE_LCHILD (pn)))
return (FALSE);
if ((pn->pnRight != 0) && (!GetCXTL ((pnode_t)NODE_RCHILD (pn))))
return (FALSE);
return (TRUE);
}
}
/** GetExpr - get expression from bound expression tree
* status = GetExpr (radix, phStr, pEnd);
* Entry radix = numeric radix for formatting
* phStr = pointer to handle for formatted string
* pEnd = pointer to int to receive index of char that ended parse
* Exit *phStr = handle for allocated expression
* *pEnd = index of character that terminated parse
* Returns EENOERROR if no error
* error number if
*/
EESTATUS
GetExpr (
uint radix,
PEEHSTR phStr,
ulong *pEnd
)
{
EESTATUS retval = EENOMEMORY;
char *pStr;
char *pExprStr;
HDEP hExprStr;
int len;
ulong strIndex;
UINT nLen;
Unreferenced( radix );
//M00KLUDGE - this routine will eventuall have to walk the bound tree
// and format the expression because of ambiguous expressions
// use the saved original string if there is one
// (in case the expression has been modified)
if (pExState->hExStrSav) {
hExprStr = pExState->hExStrSav;
len = pExState->ExLenSav;
strIndex = pExState->strIndexSav;
} else {
hExprStr = pExState->hExStr;
len = pExState->ExLen;
strIndex = pExState->strIndex;
}
pExprStr = (char *) MemLock (hExprStr);
nLen = len+1;
if (((*phStr = MemAllocate (nLen)) != 0)) {
// the expression has been bound and memory allocated
char tempBuf[TYPESTRMAX];
UINT nb;
UINT nIndex = 0;
BOOL fHSYM;
char *psz;
ulong nAdj = 0;
pStr = (char *) MemLock (*phStr);
for (psz = pExprStr; (psz < pExprStr + len) && *psz; psz = _tcsinc (psz)) {
fHSYM = FALSE;
if (*psz == HSYM_MARKER) {
HSYM hSym = GetHSYMFromHSYMCode(psz + 1);
psz += HSYM_CODE_LEN; // skip embedded HSYM code
fHSYM = TRUE;
DASSERT (hSym);
if (GetNameFromHSYM(tempBuf, hSym) == FALSE) {
pExState->err_num = ERR_INTERNAL;
MemUnLock(*phStr);
MemUnLock(hExprStr);
return EEGENERAL;
}
nb = _tcslen(tempBuf);
// compute adjustment for strIndex:
// if an HSYM is to the left of strIndex,
// strIndex needs to be adjusted
if (psz <= pExprStr + strIndex)
nAdj += (nb - sizeof (char) - HSYM_CODE_LEN);
} else {
nb = 1;
}
// check if there is space in the buffer and
// copy nb characters to the destination string
if (nIndex + nb > nLen-1) {
// there is not enough space, grow buffer
MemUnLock(*phStr);
nLen += NAMESTRMAX;
if ((*phStr = MemReAlloc(*phStr, nLen)) == 0){
MemUnLock(hExprStr);
return EENOMEMORY;
}
pStr = (char *) MemLock (*phStr);
}
if (fHSYM) {
// copy name from tembBuf
memcpy(pStr+nIndex, tempBuf, nb);
nIndex += nb;
} else {
// copy a single character from pExprStr
_tccpy (pStr + nIndex, psz);
nIndex += _tclen (psz);
}
}
pStr[nIndex++] = 0;
MemUnLock (*phStr);
// Reallocate the buffer in case it is too large
DASSERT (nIndex <= nLen);
if (nIndex < nLen &&
(*phStr = MemReAlloc(*phStr, nIndex)) == 0){
MemUnLock(hExprStr);
return EENOMEMORY;
}
retval = EENOERROR;
*pEnd = strIndex + nAdj;
}
MemUnLock (hExprStr);
return retval;
}
/** PushCXT - Push CXT list entry
* fSuccess = PushCXT (pv)
* Entry pv = pointer to evaluation
* hCxtl = handle of CXT list
* pCxtl = pointer to CXT list
* mCxtl = maximum number of context list entries
* Exit CXT entry pushed
* Returns TRUE if no error
* FALSE if error
*/
bool_t
PushCXT (
peval_t pv
)
{
HCXTL nhCxtl;
PCXTL npCxtl;
uint lenIn;
uint lenOut;
DASSERT (pCxtl->cHCS <= mCxtl);
if (mCxtl < pCxtl->cHCS) {
// this is a catatrosphic error
return (FALSE);
}
if (mCxtl == pCxtl->cHCS) {
// grow CXT list
lenIn = sizeof (CXTL) + mCxtl * sizeof (HCS);
lenOut = sizeof (CXTL) + (mCxtl + 5) * sizeof (HCS);
if ((nhCxtl = MemAllocate (lenOut)) == 0) {
return (FALSE);
}
npCxtl = (PCXTL) MemLock (nhCxtl);
memcpy (npCxtl, pCxtl, lenIn);
mCxtl += 5;
MemUnLock (hCxtl);
MHMemFree (hCxtl);
hCxtl = nhCxtl;
pCxtl = npCxtl;
}
// in case of a constant we will return only the context information.
// anything more than that doesn't make sense and since we
// need to get context only information in the case of bp {..}.line
// we needed to make this change.
pCxtl->rgHCS[pCxtl->cHCS].hSym = pv->hSym;
// Change for Dolphin bp functionality:
// if pv->CXTT is non-zero, prefer it over *pCxt:
// pv->CXTT is more specific, as it contains the exact
// context where a symbol was found by SearchSym, while
// pCxt just contains a context from which the symbol is
// visible
pCxtl->rgHCS[pCxtl->cHCS].CXT = (pv->CXTT.hMod) ? pv->CXTT : *pCxt;
pCxtl->cHCS++;
return (TRUE);
}
bool_t
GetCXTFunction (
pnode_t pnLeft,
pnode_t pnRight
)
{
Unreferenced( pnLeft );
Unreferenced( pnRight );
return (FALSE);
}