7599 lines
269 KiB
C
7599 lines
269 KiB
C
|
/*** DEBSYM.C - symbol lookup routines for expression evaluator
|
||
|
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include "debexpr.h"
|
||
|
#include "debsym.h"
|
||
|
|
||
|
|
||
|
#define WINDBG_POINTERS_MACROS_ONLY
|
||
|
#include "sundown.h"
|
||
|
#undef WINDBG_POINTERS_MACROS_ONLY
|
||
|
|
||
|
|
||
|
|
||
|
// enum specifying return from IsDominated
|
||
|
|
||
|
typedef enum {
|
||
|
DOM_ambiguous,
|
||
|
DOM_keep,
|
||
|
DOM_replace
|
||
|
} DOM_t;
|
||
|
|
||
|
// Return values from SearchClassName
|
||
|
|
||
|
typedef enum {
|
||
|
SCN_error, // error, abort search
|
||
|
SCN_notfound, // not found
|
||
|
SCN_found, // found
|
||
|
SCN_rewrite // found and this pointer inserted
|
||
|
} SCN_t;
|
||
|
|
||
|
|
||
|
// Return values from MatchMethod
|
||
|
|
||
|
typedef enum {
|
||
|
MTH_error, // error - abort search
|
||
|
MTH_found, // found without error
|
||
|
} MTH_t;
|
||
|
|
||
|
|
||
|
typedef struct HSL_restart_t {
|
||
|
search_t Name;
|
||
|
HSYM hSym;
|
||
|
HSYML_t state;
|
||
|
ulong mask;
|
||
|
} HSL_restart_t;
|
||
|
|
||
|
|
||
|
static char *vtabptr = "#vptr#";
|
||
|
static HDEP hSymClass = 0;
|
||
|
static psymclass_t pSymClass = NULL;
|
||
|
|
||
|
static HDEP hVBDom = 0;
|
||
|
static pdombase_t pVBDom = NULL;
|
||
|
|
||
|
static HDEP hVBSearch = 0;
|
||
|
static pdombase_t pVBSearch = NULL;
|
||
|
static psearch_t pNameFirst = NULL;
|
||
|
|
||
|
pnode_t AddETConst (pnode_t, UOFFSET, CV_typ_t);
|
||
|
pnode_t AddETExpr (pnode_t, CV_typ_t, UOFFSET, UOFFSET, CV_typ_t);
|
||
|
pnode_t AddETInit (pnode_t, CV_typ_t);
|
||
|
bool_t AddHSYM (psearch_t, HSYM, PHSL_HEAD *, ulong, HDEP * );
|
||
|
SCN_t AddVBList (psymclass_t, pdombase_t *, HDEP *);
|
||
|
SCN_t AddVBType (pdombase_t *, HDEP *, CV_typ_t);
|
||
|
ulong AmbFromList (psearch_t);
|
||
|
bool_t AmbToList (psearch_t);
|
||
|
bool_t CheckDupAmb (psearch_t);
|
||
|
bool_t DebLoadConst (peval_t, CONSTPTR, HSYM);
|
||
|
SCN_t DupSymCl (psearch_t);
|
||
|
SCN_t FindIntro (psearch_t);
|
||
|
SCN_t GenQualExpr (psearch_t);
|
||
|
HDEP GenQualName (psearch_t, psymclass_t);
|
||
|
bool_t GrowTMList (void);
|
||
|
SCN_t IncrSymBase (void);
|
||
|
bool_t InitMod (psearch_t);
|
||
|
DOM_t IsDominated (psymclass_t, psymclass_t);
|
||
|
bool_t IsIntroVirtInMlist (ulong , CV_typ_t, UOFFSET *);
|
||
|
bool_t IsIntroVirt (CV_typ_t);
|
||
|
bool_t LineNumber (psearch_t);
|
||
|
void MatchArgs (peval_t, psearch_t, CV_fldattr_t, UOFFSET, bool_t);
|
||
|
HR_t FASTCALL MatchFunction (psearch_t);
|
||
|
void MoveSymCl (HDEP hSymCl);
|
||
|
SCN_t OverloadToAmbList (psearch_t, psymclass_t);
|
||
|
SCN_t MethodsToAmbList (psearch_t, psymclass_t);
|
||
|
bool_t ParseRegister (psearch_t);
|
||
|
void PurgeAmbCl (psearch_t);
|
||
|
SCN_t RecurseBase (psearch_t, CV_typ_t, CV_typ_t, UOFFSET, UOFFSET, CV_fldattr_t, bool_t);
|
||
|
SCN_t RemoveAmb (psearch_t);
|
||
|
SCN_t SearchAERule (psearch_t);
|
||
|
SCN_t SearchBases (psearch_t);
|
||
|
SCN_t SearchBType (psearch_t);
|
||
|
SCN_t SearchClassName (psearch_t);
|
||
|
bool_t SearchQualName (psearch_t, psymclass_t, HDEP, bool_t);
|
||
|
SCN_t SearchRoot (psearch_t);
|
||
|
SCN_t SetBase (psearch_t, CV_typ_t, CV_typ_t, UOFFSET, UOFFSET, CV_fldattr_t, bool_t);
|
||
|
SCN_t SetBPValue (psearch_t);
|
||
|
SCN_t SetValue (psearch_t);
|
||
|
HR_t SymAmbToList (psearch_t);
|
||
|
CV_typ_t SkipModifiers(HMOD mod, CV_typ_t type);
|
||
|
bool_t SymToNode (psearch_t);
|
||
|
bool_t VBSearched (CV_typ_t);
|
||
|
bool_t VBaseFound (psearch_t);
|
||
|
|
||
|
bool_t FASTCALL InsertThis (psearch_t);
|
||
|
MTH_t MatchMethod (psearch_t, psymclass_t);
|
||
|
|
||
|
// NOTE: OpName[0] MUST be the this string
|
||
|
|
||
|
OPNAME OpName[] = {
|
||
|
{"\x004""this"}, // OP_this
|
||
|
{"\x00b""operator->*"}, // OP_Opmember
|
||
|
{"\x00b""operator>>="}, // OP_Orightequal
|
||
|
{"\x00b""operator<<="}, // OP_Oleftequal
|
||
|
{"\x00a""operator()"}, // OP_Ofunction
|
||
|
{"\x00a""operator[]"}, // OP_Oarray
|
||
|
{"\x00a""operator+="}, // OP_Oplusequal
|
||
|
{"\x00a""operator-="}, // OP_Ominusequal
|
||
|
{"\x00a""operator*="}, // OP_Otimesequal
|
||
|
{"\x00a""operator/="}, // OP_Odivequal
|
||
|
{"\x00a""operator%="}, // OP_Opcentequal
|
||
|
{"\x00a""operator&="}, // OP_Oandequal
|
||
|
{"\x00a""operator^="}, // OP_Oxorequal
|
||
|
{"\x00a""operator|="}, // OP_Oorequal
|
||
|
{"\x00a""operator<<"}, // OP_Oshl
|
||
|
{"\x00a""operator>>"}, // OP_Oshr
|
||
|
{"\x00a""operator=="}, // OP_Oequalequal
|
||
|
{"\x00a""operator!="}, // OP_Obangequal
|
||
|
{"\x00a""operator<="}, // OP_Olessequal
|
||
|
{"\x00a""operator>="}, // OP_Ogreatequal
|
||
|
{"\x00a""operator&&"}, // OP_Oandand
|
||
|
{"\x00a""operator||"}, // OP_Ooror
|
||
|
{"\x00a""operator++"}, // OP_Oincrement
|
||
|
{"\x00a""operator--"}, // OP_Odecrement
|
||
|
{"\x00a""operator->"}, // OP_Opointsto
|
||
|
{"\x009""operator+"}, // OP_Oplus
|
||
|
{"\x009""operator-"}, // OP_Ominus
|
||
|
{"\x009""operator*"}, // OP_Ostar
|
||
|
{"\x009""operator/"}, // OP_Odivide
|
||
|
{"\x009""operator%"}, // OP_Opercent
|
||
|
{"\x009""operator^"}, // OP_Oxor
|
||
|
{"\x009""operator&"}, // OP_Oand
|
||
|
{"\x009""operator|"}, // OP_Oor
|
||
|
{"\x009""operator~"}, // OP_Otilde
|
||
|
{"\x009""operator!"}, // OP_Obang
|
||
|
{"\x009""operator="}, // OP_Oequal
|
||
|
{"\x009""operator<"}, // OP_Oless
|
||
|
{"\x009""operator>"}, // OP_Ogreater
|
||
|
{"\x009""operator,"}, // OP_Ocomma
|
||
|
{"\x012""operator new"}, // OP_Onew
|
||
|
{"\x015""operator delete"} // OP_Odelete
|
||
|
};
|
||
|
|
||
|
|
||
|
// Symbol searching and search initialization routines
|
||
|
|
||
|
|
||
|
|
||
|
/** InitSearchBase - initialize search for base class
|
||
|
|
||
|
* InitSearchBase (bnOp, typD, typ, pName, pv)
|
||
|
|
||
|
* Entry bnOp = based pointer to OP_cast node
|
||
|
* bn = based pointer to cast string
|
||
|
* typD = type of derived class
|
||
|
* typB = type of desired base class
|
||
|
* pName = pointer to symbol search structure
|
||
|
* pv = pointer to value node
|
||
|
|
||
|
* Exit search structure initialized for SearchSym
|
||
|
|
||
|
* Returns pointer to search symbol structure
|
||
|
*/
|
||
|
|
||
|
|
||
|
void
|
||
|
InitSearchBase (
|
||
|
bnode_t bnOp,
|
||
|
CV_typ_t typD,
|
||
|
CV_typ_t typB,
|
||
|
psearch_t pName,
|
||
|
peval_t pv
|
||
|
)
|
||
|
{
|
||
|
// set starting context for symbol search to current context
|
||
|
|
||
|
memset (pName, 0, sizeof (*pName));
|
||
|
pName->initializer = INIT_base;
|
||
|
pName->pv = pv;
|
||
|
pName->typeIn = typD;
|
||
|
pName->typeOut = typB;
|
||
|
pName->scope = SCP_class;
|
||
|
pName->CXTT = *pCxt;
|
||
|
pName->bn = 0;
|
||
|
pName->bnOp = bnOp;
|
||
|
pName->state = SYM_bclass;
|
||
|
pName->CurClass = typD;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef NEVER
|
||
|
/** InitSearchtDef - initialize typedef symbol search
|
||
|
|
||
|
* InitSearctDef (pName, iClass, tDef, scope, clsmask)
|
||
|
|
||
|
* Entry iClass = initial class if explicit class reference
|
||
|
* tDef = index of typedef
|
||
|
* scope = mask describing scope of search
|
||
|
* clsmask = mask describing permitted class elements
|
||
|
|
||
|
* Exit search structure initialized for SearchSym
|
||
|
|
||
|
* Returns pointer to search symbol structure
|
||
|
*/
|
||
|
|
||
|
|
||
|
void
|
||
|
InitSearchtDef (
|
||
|
psearch_t pName,
|
||
|
peval_t pv,
|
||
|
ulong scope
|
||
|
)
|
||
|
{
|
||
|
char NullString = 0;
|
||
|
|
||
|
// set starting context for symbol search to current context
|
||
|
|
||
|
memset (pName, 0, sizeof (*pName));
|
||
|
pName->initializer = INIT_tdef;
|
||
|
pName->sstr.lpName = &NullString;
|
||
|
pName->sstr.cb = 0;
|
||
|
pName->pfnCmp = TDCMP;
|
||
|
pName->scope = scope;
|
||
|
pName->CXTT = *pCxt;
|
||
|
pName->pv = pv;
|
||
|
pName->typeIn = EVAL_TYP (pv);
|
||
|
pName->sstr.searchmask |= SSTR_symboltype | SSTR_NoHash;
|
||
|
pName->sstr.symtype = S_UDT;
|
||
|
pName->state = SYM_init;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/** InitSearchAERule - initialize search for auto-expansion rule
|
||
|
|
||
|
* InitSearchAErule (pName, pv, typ, hMod)
|
||
|
|
||
|
* Entry pName = pointer to search structure
|
||
|
* pv = pointer to eval_node to receive result
|
||
|
* typ = type index of class to be auto-expanded
|
||
|
* hMod = handle to module where typ is defined
|
||
|
|
||
|
* Exit search structure initialized for SearchSym
|
||
|
|
||
|
* Returns void
|
||
|
*/
|
||
|
void
|
||
|
InitSearchAErule (
|
||
|
psearch_t pName,
|
||
|
peval_t pv,
|
||
|
CV_typ_t typ,
|
||
|
HMOD hMod
|
||
|
)
|
||
|
{
|
||
|
// set starting context for symbol search to current context
|
||
|
|
||
|
memset (pName, 0, sizeof (*pName));
|
||
|
pName->initializer = INIT_AErule;
|
||
|
pName->pfnCmp = 0;
|
||
|
pName->sstr.lpName = (uchar *) "";
|
||
|
pName->pv = pv;
|
||
|
SHGetCxtFromHmod (hMod, &pName->CXTT);
|
||
|
|
||
|
pName->state = SYM_init;
|
||
|
// restrict searching to class scope
|
||
|
pName->ExpClass = typ;
|
||
|
pName->scope = SCP_class;
|
||
|
}
|
||
|
|
||
|
|
||
|
/** SearchCFlag - initialize compile flags symbol search
|
||
|
|
||
|
* SearchCFlag (pName, iClass, scope, clsmask)
|
||
|
|
||
|
* Entry pName = pointer to symbol search structure
|
||
|
|
||
|
* Exit search structure initialized for SearchSym
|
||
|
|
||
|
* Returns pointer to search symbol structure
|
||
|
*/
|
||
|
|
||
|
|
||
|
HSYM
|
||
|
SearchCFlag (void)
|
||
|
{
|
||
|
search_t Name;
|
||
|
CXT CXTTOut;
|
||
|
|
||
|
// set starting context for symbol search to current context
|
||
|
|
||
|
memset (&Name, 0, sizeof (Name));
|
||
|
Name.pfnCmp = (PFNCMP) CSCMP;
|
||
|
Name.CXTT = *pCxt;
|
||
|
Name.sstr.searchmask |= SSTR_symboltype;
|
||
|
Name.sstr.symtype = S_COMPILE;
|
||
|
if (InitMod (&Name) == TRUE) {
|
||
|
SHGetCxtFromHmod (Name.hMod, &Name.CXTT);
|
||
|
if ((Name.hSym = SHFindNameInContext (Name.hSym,
|
||
|
&Name.CXTT,
|
||
|
&Name.sstr,
|
||
|
pExState->state.fCase,
|
||
|
Name.pfnCmp,
|
||
|
&CXTTOut)) != 0)
|
||
|
{
|
||
|
return (Name.hSym);
|
||
|
}
|
||
|
}
|
||
|
// error in context initialization or compile flag symbol not found
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** SetAmbiant - set ambiant code or data model
|
||
|
|
||
|
* mode = SetAmbiant (flag)
|
||
|
|
||
|
* Entry flag = TRUE if ambiant data model
|
||
|
* flag = FALSE if ambiant code model
|
||
|
|
||
|
* Exit none
|
||
|
|
||
|
* Returns ambiant model C7_... from the compile flags symbol
|
||
|
* if the compile flags symbol is not found, C7_NEAR is returned
|
||
|
*/
|
||
|
|
||
|
|
||
|
CV_ptrtype_e
|
||
|
SetAmbiant (
|
||
|
bool_t isdata
|
||
|
)
|
||
|
{
|
||
|
HSYM hCFlag;
|
||
|
CFLAGPTR pCFlag;
|
||
|
CV_ptrtype_e type;
|
||
|
|
||
|
Unreferenced( isdata );
|
||
|
type = (TargetMachine == mptia64)? CV_PTR_64: CV_PTR_NEAR32;
|
||
|
|
||
|
#if !defined(TARGMAC68K)
|
||
|
if ((hCFlag = SearchCFlag ()) == 0) {
|
||
|
// compile flag symbol not found, set model to near or near32
|
||
|
} else {
|
||
|
pCFlag = (CFLAGPTR) MHOmfLock (hCFlag);
|
||
|
switch (pCFlag->flags.ambdata) {
|
||
|
default:
|
||
|
DASSERT (FALSE);
|
||
|
case CV_CFL_DNEAR:
|
||
|
type = (TargetMachine == mptia64)? CV_PTR_64: CV_PTR_NEAR32;
|
||
|
break;
|
||
|
|
||
|
case CV_CFL_DFAR:
|
||
|
type = CV_PTR_FAR32;
|
||
|
break;
|
||
|
|
||
|
case CV_CFL_DHUGE:
|
||
|
type = CV_PTR_HUGE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
MHOmfUnLock (hCFlag);
|
||
|
#else
|
||
|
Unreferenced(hCFlag);
|
||
|
Unreferenced(pCFlag);
|
||
|
#endif
|
||
|
|
||
|
return (type);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** GetHSYMList - get HSYM list for context
|
||
|
|
||
|
* status = EEGetHSYMList (phSYMl, pCXT, mask, pRE, fEnableProlog)
|
||
|
|
||
|
* Entry phSYML = pointer to handle to symbol list
|
||
|
* pCXT = pointer to context
|
||
|
* mask = selection mask
|
||
|
* pRE = pointer to regular expression
|
||
|
* fEnableProlog = FALSE if function scoped symbols only after prolog
|
||
|
* fEnableProlog = TRUE if function scoped symbols during prolog
|
||
|
|
||
|
* Exit *phMem = handle for HSYM list buffer
|
||
|
|
||
|
* Returns EENOERROR if no error
|
||
|
* status code if error
|
||
|
*/
|
||
|
|
||
|
|
||
|
EESTATUS
|
||
|
GetHSYMList (
|
||
|
HDEP *phSYML,
|
||
|
PCXT pCxt,
|
||
|
ulong mask,
|
||
|
uchar *pRE,
|
||
|
SHFLAG fEnableProlog
|
||
|
)
|
||
|
{
|
||
|
search_t Name = {0};
|
||
|
CXT CXTTOut;
|
||
|
HSYM hSym = 0;
|
||
|
PHSL_HEAD pHSLHead;
|
||
|
HSYML_t state;
|
||
|
HSL_restart_t *pRestart;
|
||
|
bool_t fRestart;
|
||
|
bool_t isprolog;
|
||
|
bool_t fCaseSensitive;
|
||
|
|
||
|
if (mask & HSYMR_nocase) {
|
||
|
mask &= ~HSYMR_nocase;
|
||
|
fCaseSensitive = FALSE;
|
||
|
} else
|
||
|
fCaseSensitive = TRUE;
|
||
|
|
||
|
if (*phSYML == 0) {
|
||
|
// allocate and initialize buffer
|
||
|
|
||
|
if ((*phSYML = MemAllocate (HSYML_SIZE)) == 0) {
|
||
|
return (EECATASTROPHIC);
|
||
|
}
|
||
|
pHSLHead = (PHSL_HEAD) MemLock (*phSYML);
|
||
|
memset (pHSLHead, 0, pHSLHead->size);
|
||
|
|
||
|
pHSLHead->size = HSYML_SIZE;
|
||
|
pHSLHead->remaining = pHSLHead->size - sizeof ( HSL_HEAD );
|
||
|
pHSLHead->pHSLList = (PHSL_LIST)(((uchar *)pHSLHead) + sizeof (HSL_HEAD));
|
||
|
state = HSYML_lexical;
|
||
|
Name.initializer = INIT_RE;
|
||
|
Name.pfnCmp = (PFNCMP) FNCMP;
|
||
|
Name.sstr.searchmask |= SSTR_RE;
|
||
|
Name.CXTT = *pCxt;
|
||
|
Name.hMod = pCxt->hMod;
|
||
|
if ( pCxt->hMod ) {
|
||
|
Name.hExe = SHHexeFromHmod ( pCxt->hMod );
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
// not valid to call SHHexeFromHmod with an Hmod of 0,
|
||
|
// so set Hexe explicitly
|
||
|
Name.hExe = 0;
|
||
|
}
|
||
|
if ( pRE && *pRE ) {
|
||
|
Name.sstr.pRE = pRE;
|
||
|
}
|
||
|
fRestart = FALSE;
|
||
|
}
|
||
|
else {
|
||
|
pHSLHead = (PHSL_HEAD) MemLock (*phSYML);
|
||
|
pRestart = (HSL_restart_t *) MemLock (pHSLHead->restart);
|
||
|
Name = pRestart->Name;
|
||
|
mask = pRestart->mask;
|
||
|
state = pRestart->state;
|
||
|
hSym = pRestart->hSym;
|
||
|
pHSLHead->blockcnt = 0;
|
||
|
pHSLHead->symbolcnt = 0;
|
||
|
pHSLHead->remaining = pHSLHead->size - sizeof ( HSL_HEAD );
|
||
|
pHSLHead->pHSLList = (PHSL_LIST)(((uchar *)pHSLHead) + sizeof (HSL_HEAD));
|
||
|
MemUnLock (pHSLHead->restart);
|
||
|
memset ((uchar *)pHSLHead + sizeof (HSL_HEAD), 0, pHSLHead->size - sizeof (HSL_HEAD));
|
||
|
AddHSYM (&Name, hSym, &pHSLHead, state, phSYML);
|
||
|
fRestart = TRUE;
|
||
|
Name.hSym = hSym;
|
||
|
}
|
||
|
switch (state) {
|
||
|
case HSYML_lexical:
|
||
|
if (mask & HSYMR_lexical) {
|
||
|
// search up the lexical scope to but not including the
|
||
|
// function level
|
||
|
|
||
|
while (SHIsCXTBlk (&Name.CXTT)) {
|
||
|
while ((hSym = SHFindNameInContext (Name.hSym,
|
||
|
&Name.CXTT,
|
||
|
&Name.sstr,
|
||
|
fCaseSensitive,
|
||
|
(PFNCMP) FNCMP,
|
||
|
&CXTTOut)) != 0) {
|
||
|
if (AddHSYM (&Name, hSym, &pHSLHead, HSYMR_lexical, phSYML) == FALSE) {
|
||
|
goto hsyml_exit;
|
||
|
}
|
||
|
Name.hSym = hSym;
|
||
|
}
|
||
|
|
||
|
// go to the parent scope
|
||
|
|
||
|
SHGoToParent (&Name.CXTT, &CXTTOut);
|
||
|
// reset current symbol
|
||
|
Name.CXTT = CXTTOut;
|
||
|
Name.hSym = 0;
|
||
|
}
|
||
|
mask &= ~HSYMR_lexical;
|
||
|
}
|
||
|
|
||
|
case HSYML_function:
|
||
|
if (mask & HSYMR_function) {
|
||
|
if (fRestart == FALSE) {
|
||
|
Name.hSym = 0;
|
||
|
Name.CXTT.hBlk = 0;
|
||
|
}
|
||
|
fRestart = FALSE;
|
||
|
state = HSYML_function;
|
||
|
|
||
|
if ( Name.CXTT.hMod != 0 ) {
|
||
|
isprolog = SHIsInProlog (&Name.CXTT);
|
||
|
}
|
||
|
while (!SHIsCXTMod (&Name.CXTT) && Name.CXTT.hMod != 0) {
|
||
|
while ((hSym = SHFindNameInContext ( Name.hSym,
|
||
|
&Name.CXTT,
|
||
|
&Name.sstr,
|
||
|
fCaseSensitive,
|
||
|
(PFNCMP) FNCMP,
|
||
|
&CXTTOut)) != 0
|
||
|
) {
|
||
|
BOOL fAddSym = TRUE;
|
||
|
|
||
|
if ((isprolog == TRUE) && (fEnableProlog == FALSE)) {
|
||
|
// we want to reject bp_relative and register
|
||
|
// stuff if we are in the prolog or epilog of
|
||
|
// a function
|
||
|
|
||
|
if (!fValidInProlog (hSym, FALSE)) {
|
||
|
fAddSym = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fAddSym ) {
|
||
|
ulong len;
|
||
|
SYMPTR pSym = (SYMPTR) MHOmfLock (hSym);
|
||
|
|
||
|
switch (pSym->rectyp) {
|
||
|
case S_BPREL32:
|
||
|
if (((BPRELPTR32)pSym)->off >= 0) {
|
||
|
// This is a formal argument
|
||
|
len = ((BPRELPTR32)pSym)->name[0];
|
||
|
if ((len == 12) &&
|
||
|
(_tcsncmp((_TXCHAR *) ((BPRELPTR32)pSym)->name+1, "__$ReturnUdt", len) == 0)) {
|
||
|
fAddSym = FALSE;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case S_REGREL32:
|
||
|
if (((LPREGREL32)pSym)->off >= 0) {
|
||
|
// Formal parameter
|
||
|
len = ((LPREGREL32)pSym)->name[0];
|
||
|
if ((len == 12) &&
|
||
|
(_tcsncmp((_TXCHAR *) ((LPREGREL32)pSym)->name+1, "__$ReturnUdt", len) == 0)) {
|
||
|
fAddSym = FALSE;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
fAddSym = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
MHOmfUnLock (hSym);
|
||
|
}
|
||
|
|
||
|
if ( fAddSym ) {
|
||
|
if (AddHSYM (&Name, hSym, &pHSLHead, HSYMR_function, phSYML) == FALSE) {
|
||
|
goto hsyml_exit;
|
||
|
}
|
||
|
}
|
||
|
Name.hSym = hSym;
|
||
|
}
|
||
|
|
||
|
// go to the parent scope
|
||
|
|
||
|
SHGoToParent (&Name.CXTT, &CXTTOut);
|
||
|
// reset current symbol
|
||
|
Name.CXTT = CXTTOut;
|
||
|
Name.hSym = 0;
|
||
|
}
|
||
|
mask &= ~HSYMR_function;
|
||
|
}
|
||
|
|
||
|
|
||
|
case HSYML_class:
|
||
|
if (mask & HSYMR_class) {
|
||
|
if (fRestart == FALSE) {
|
||
|
Name.hSym = 0;
|
||
|
if (ClassImp != 0) {
|
||
|
Name.CurClass = ClassImp;
|
||
|
}
|
||
|
}
|
||
|
fRestart = FALSE;
|
||
|
|
||
|
if ((Name.CurClass != 0)) {
|
||
|
DASSERT (FALSE);
|
||
|
// need to do equivalent of EEGetChild on this
|
||
|
}
|
||
|
mask &= ~HSYMR_class;
|
||
|
}
|
||
|
|
||
|
case HSYML_module:
|
||
|
if (mask & HSYMR_module) {
|
||
|
if (fRestart == FALSE) {
|
||
|
SHGetCxtFromHmod (Name.hMod, &Name.CXTT);
|
||
|
Name.hSym = 0;
|
||
|
}
|
||
|
fRestart = FALSE;
|
||
|
Name.state = (symstate_t) HSYML_module;
|
||
|
while ((hSym = SHFindNameInContext (Name.hSym,
|
||
|
&Name.CXTT,
|
||
|
&Name.sstr,
|
||
|
fCaseSensitive,
|
||
|
Name.pfnCmp,
|
||
|
&CXTTOut)) != 0)
|
||
|
{
|
||
|
if (AddHSYM (&Name, hSym, &pHSLHead, HSYMR_module, phSYML) == FALSE) {
|
||
|
goto hsyml_exit;
|
||
|
}
|
||
|
Name.hSym = hSym;
|
||
|
}
|
||
|
mask &= ~HSYMR_module;
|
||
|
}
|
||
|
|
||
|
case HSYML_global:
|
||
|
// search global symbol table
|
||
|
if (mask & HSYMR_global) {
|
||
|
if (fRestart == FALSE) {
|
||
|
Name.hSym = 0;
|
||
|
}
|
||
|
fRestart = FALSE;
|
||
|
Name.state = (symstate_t) HSYML_global;
|
||
|
Name.sstr.searchmask |= SSTR_NoHash;
|
||
|
while ((hSym = SHFindNameInGlobal (Name.hSym,
|
||
|
&Name.CXTT,
|
||
|
&Name.sstr,
|
||
|
fCaseSensitive,
|
||
|
Name.pfnCmp,
|
||
|
&CXTTOut)) != 0)
|
||
|
{
|
||
|
if (AddHSYM (&Name, hSym, &pHSLHead, HSYMR_global, phSYML) == FALSE) {
|
||
|
goto hsyml_exit;
|
||
|
}
|
||
|
Name.hSym = hSym;
|
||
|
}
|
||
|
mask &= ~HSYMR_global;
|
||
|
}
|
||
|
|
||
|
case HSYML_exe:
|
||
|
if (mask & HSYMR_exe) {
|
||
|
Name.state = (symstate_t) HSYML_exe;
|
||
|
if (fRestart == FALSE) {
|
||
|
Name.hModCur = SHGetNextMod (Name.hExe, Name.hMod);
|
||
|
Name.hSym = 0;
|
||
|
}
|
||
|
fRestart = FALSE;
|
||
|
Name.sstr.searchmask |= SSTR_NoHash;
|
||
|
do {
|
||
|
SHGetCxtFromHmod (Name.hModCur, &Name.CXTT);
|
||
|
while ((hSym = SHFindNameInContext (Name.hSym,
|
||
|
&Name.CXTT,
|
||
|
&Name.sstr,
|
||
|
fCaseSensitive,
|
||
|
Name.pfnCmp,
|
||
|
&CXTTOut)) != 0)
|
||
|
{
|
||
|
if (AddHSYM (&Name, hSym, &pHSLHead, HSYMR_exe, phSYML) == FALSE) {
|
||
|
goto hsyml_exit;
|
||
|
}
|
||
|
Name.hSym = hSym;
|
||
|
}
|
||
|
} while (Name.hSym = 0,
|
||
|
(Name.hModCur = SHGetNextMod (Name.hExe, Name.hModCur)) != Name.hMod);
|
||
|
mask &= ~HSYMR_exe;
|
||
|
}
|
||
|
|
||
|
case HSYML_public:
|
||
|
if (mask & HSYMR_public && Name.hExe) {
|
||
|
if (fRestart == FALSE) {
|
||
|
hSym = 0;
|
||
|
}
|
||
|
fRestart = FALSE;
|
||
|
Name.state = (symstate_t) HSYML_public;
|
||
|
Name.sstr.searchmask |= SSTR_NoHash;
|
||
|
while ((hSym = PHFindNameInPublics (hSym, Name.hExe,
|
||
|
&Name.sstr, fCaseSensitive, Name.pfnCmp)) != 0) {
|
||
|
if (AddHSYM (&Name, hSym, &pHSLHead, HSYMR_public, phSYML) == FALSE) {
|
||
|
goto hsyml_exit;
|
||
|
}
|
||
|
Name.hSym = hSym;
|
||
|
}
|
||
|
mask &= ~HSYMR_public;
|
||
|
}
|
||
|
}
|
||
|
pHSLHead->status.endsearch = TRUE;
|
||
|
MemUnLock (*phSYML);
|
||
|
return (EENOERROR);
|
||
|
|
||
|
hsyml_exit:
|
||
|
if (pHSLHead->restart == 0) {
|
||
|
// allocate restart buffer
|
||
|
|
||
|
if ((pHSLHead->restart = MemAllocate (sizeof (HSL_restart_t))) == 0) {
|
||
|
pHSLHead->status.fatal = TRUE;
|
||
|
MemUnLock (*phSYML);
|
||
|
return (EENOMEMORY);
|
||
|
}
|
||
|
}
|
||
|
pRestart = (HSL_restart_t *) MemLock (pHSLHead->restart);
|
||
|
pRestart->Name = Name;
|
||
|
pRestart->mask = mask;
|
||
|
pRestart->state = state;
|
||
|
pRestart->hSym = hSym;
|
||
|
MemUnLock (pHSLHead->restart);
|
||
|
MemUnLock (*phSYML);
|
||
|
return (EENOERROR);
|
||
|
}
|
||
|
|
||
|
|
||
|
bool_t
|
||
|
GrowHSL(
|
||
|
HDEP *phSYML,
|
||
|
PHSL_HEAD *ppHSLHead
|
||
|
)
|
||
|
{
|
||
|
unsigned int bias;
|
||
|
int newsize;
|
||
|
HDEP h;
|
||
|
|
||
|
bias = (unsigned int)((uchar *)(*ppHSLHead)->pHSLList - (uchar *)(*ppHSLHead));
|
||
|
newsize = (*ppHSLHead)->size + HSYML_SIZE;
|
||
|
|
||
|
MemUnLock(*phSYML);
|
||
|
|
||
|
h = MemReAlloc(*phSYML, newsize);
|
||
|
if (!h) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
*phSYML = h;
|
||
|
*ppHSLHead = MemLock(h);
|
||
|
|
||
|
(*ppHSLHead)->size += HSYML_SIZE;
|
||
|
(*ppHSLHead)->remaining += HSYML_SIZE;
|
||
|
(*ppHSLHead)->pHSLList = (PHSL_LIST) ( (uchar *)(*ppHSLHead) + bias );
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool_t
|
||
|
AddHSYM (
|
||
|
psearch_t pName,
|
||
|
HSYM hSym,
|
||
|
PHSL_HEAD *ppHSLHead,
|
||
|
ulong request,
|
||
|
HDEP *phSYML
|
||
|
)
|
||
|
{
|
||
|
PHSL_LIST pHSLList;
|
||
|
|
||
|
pHSLList = (*ppHSLHead)->pHSLList;
|
||
|
|
||
|
|
||
|
// check usability of current block
|
||
|
|
||
|
if (pHSLList->status.isused == TRUE) {
|
||
|
|
||
|
// block has been used, check for same context
|
||
|
|
||
|
|
||
|
if (memcmp (&pHSLList->Cxt, &pName->CXTT, sizeof (CXT)) != 0) {
|
||
|
|
||
|
// context has changed
|
||
|
|
||
|
|
||
|
pHSLList->status.complete = TRUE;
|
||
|
|
||
|
|
||
|
// Allocate a new HSL_LIST at the end of the list.
|
||
|
// grow the list if it is full.
|
||
|
|
||
|
if ((*ppHSLHead)->remaining < sizeof(HSL_LIST) + sizeof(HSYM)) {
|
||
|
if (!GrowHSL(phSYML, ppHSLHead)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// this will be decremented in the !hascxt code below
|
||
|
//(*ppHSLHead)->remaining -= sizeof( HSL_LIST );
|
||
|
|
||
|
|
||
|
// Point the pointer to the new list:
|
||
|
|
||
|
|
||
|
(*ppHSLHead)->pHSLList = (PHSL_LIST)(
|
||
|
(uchar *)((*ppHSLHead)->pHSLList) +
|
||
|
sizeof ( HSL_LIST ) +
|
||
|
(*ppHSLHead)->pHSLList->symbolcnt * sizeof ( HSYM ) );
|
||
|
|
||
|
pHSLList = (*ppHSLHead)->pHSLList;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pHSLList->status.hascxt == FALSE) {
|
||
|
(*ppHSLHead)->blockcnt++;
|
||
|
(*ppHSLHead)->remaining -= sizeof (HSL_LIST);
|
||
|
pHSLList->status.hascxt = TRUE;
|
||
|
pHSLList->Cxt = pName->CXTT;
|
||
|
pHSLList->request = request;
|
||
|
}
|
||
|
|
||
|
|
||
|
// grow the list if it is full.
|
||
|
|
||
|
if ((*ppHSLHead)->remaining < sizeof (HSYM)) {
|
||
|
if (!GrowHSL(phSYML, ppHSLHead)) {
|
||
|
return FALSE;
|
||
|
} else {
|
||
|
pHSLList = (*ppHSLHead)->pHSLList;
|
||
|
}
|
||
|
}
|
||
|
pHSLList->status.isused = TRUE;
|
||
|
pHSLList->hSym[pHSLList->symbolcnt++] = hSym;
|
||
|
(*ppHSLHead)->remaining -= sizeof (HSYM);
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
// search for the base sym of the base pointer
|
||
|
|
||
|
// Entry pName = structure describing the base pointer name
|
||
|
|
||
|
// Exit pName.eval reflects the bound base info
|
||
|
|
||
|
// Returns HR_ if base sym found
|
||
|
|
||
|
HR_t
|
||
|
SearchBasePtrBase (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
search_t lName = *pName;
|
||
|
plfPointer pType;
|
||
|
SYMPTR pSym;
|
||
|
unsigned short lrectyp;
|
||
|
eval_t eval;
|
||
|
peval_t lpv = &eval;
|
||
|
ulong savefEProlog = pExState->state.fEProlog;
|
||
|
HR_t retval = HR_notfound;
|
||
|
|
||
|
pExState->state.fEProlog = TRUE; // KLUDGE to get around CXT complications
|
||
|
eval = *pName->pv;
|
||
|
CLEAR_EVAL_FLAGS (lpv);
|
||
|
// an enregistered primitive
|
||
|
EVAL_IS_REG (lpv) = EVAL_IS_REG(pName->pv);
|
||
|
EVAL_IS_BPREL (lpv) = EVAL_IS_BPREL(pName->pv);
|
||
|
lName.hSym = 0; // start search at beginning of CXT
|
||
|
lName.pv = lpv;
|
||
|
DASSERT(!CV_IS_PRIMITIVE (EVAL_TYP(lpv)));
|
||
|
DASSERT (EVAL_MOD (lpv) != 0);
|
||
|
EVAL_TYPDEF (lpv) =
|
||
|
THGetTypeFromIndex (EVAL_MOD (lpv), EVAL_TYP(lpv));
|
||
|
DASSERT (EVAL_TYPDEF (lpv) != 0);
|
||
|
memset (&lpv->data, 0, sizeof (lpv->data));
|
||
|
// MOOFUTURE: This may change as new register-handling
|
||
|
// code is developed.
|
||
|
// "reg" used to be a union member of "data" but now
|
||
|
// it is a separate struct in the evaluation node (so
|
||
|
// that we can keep type information for non-trivial
|
||
|
// enregistered values). For the time, clear the reg
|
||
|
// field whenever the data field is cleared, in order to
|
||
|
// be compatible with the old EE register handling code
|
||
|
memset (&lpv->reg, 0, sizeof (lpv->reg));
|
||
|
pType = (plfPointer)(&((TYPPTR)(MHOmfLock (EVAL_TYPDEF(lpv))))->leaf);
|
||
|
DASSERT(pType->leaf == LF_POINTER);
|
||
|
DASSERT((pType->attr.ptrtype >= CV_PTR_BASE_VAL) &&
|
||
|
(pType->attr.ptrtype <= CV_PTR_BASE_SEGADDR));
|
||
|
pSym = (SYMPTR)(&((plfPointer)pType)->pbase.Sym);
|
||
|
PTR_BSYMTYPE (pName->pv) = pSym->rectyp;
|
||
|
emiAddr (PTR_ADDR (pName->pv)) = pCxt->addr.emi;
|
||
|
switch (pSym->rectyp) {
|
||
|
case S_BPREL16:
|
||
|
lName.sstr.lpName = &((BPRELPTR16)pSym)->name[1];
|
||
|
lName.sstr.cb = ((BPRELPTR16)pSym)->name[0];
|
||
|
if (SearchSym(&lName) != HR_found) {
|
||
|
goto ReturnNotFound;;
|
||
|
}
|
||
|
PopStack();
|
||
|
SetAddrSeg (&PTR_ADDR (pName->pv), 0);
|
||
|
pSym = (SYMPTR)MHOmfLock(lName.hSym);
|
||
|
if (((BPRELPTR16)pSym)->rectyp == S_BPREL16) {
|
||
|
|
||
|
SetAddrOff (&PTR_ADDR (pName->pv), ((BPRELPTR16)pSym)->off);
|
||
|
ADDR_IS_OFF32 (PTR_ADDR (pName->pv)) = FALSE;
|
||
|
ADDR_IS_FLAT (PTR_ADDR (pName->pv)) = FALSE;
|
||
|
ADDR_IS_LI (PTR_ADDR (pName->pv)) = FALSE;
|
||
|
PTR_STYPE (pName->pv) = ((BPRELPTR16)pSym)->typind;
|
||
|
|
||
|
}
|
||
|
else {
|
||
|
goto ReturnNotFound;;
|
||
|
}
|
||
|
pExState->state.bprel = TRUE;
|
||
|
break;
|
||
|
|
||
|
case S_LDATA16:
|
||
|
case S_GDATA16:
|
||
|
lName.sstr.lpName = &((DATAPTR16)pSym)->name[1];
|
||
|
lName.sstr.cb = ((DATAPTR16)pSym)->name[0];
|
||
|
lrectyp = pSym->rectyp;
|
||
|
do {
|
||
|
if (SearchSym(&lName) != HR_found) {
|
||
|
goto ReturnNotFound;;
|
||
|
}
|
||
|
PopStack();
|
||
|
pSym = (SYMPTR)MHOmfLock(lName.hSym);
|
||
|
} while (pSym->rectyp != lrectyp);
|
||
|
pExState->state.fLData = TRUE;
|
||
|
SetAddrSeg (&PTR_ADDR (pName->pv), ((DATAPTR16)pSym)->seg);
|
||
|
SetAddrOff (&PTR_ADDR (pName->pv), ((DATAPTR16)pSym)->off);
|
||
|
ADDR_IS_OFF32 (PTR_ADDR (pName->pv)) = FALSE;
|
||
|
ADDR_IS_FLAT (PTR_ADDR (pName->pv)) = FALSE;
|
||
|
ADDR_IS_LI (PTR_ADDR (pName->pv)) = TRUE;
|
||
|
PTR_STYPE (pName->pv) = ((DATAPTR16)pSym)->typind;
|
||
|
break;
|
||
|
|
||
|
case S_BPREL32:
|
||
|
lName.sstr.lpName = &((BPRELPTR32)pSym)->name[1];
|
||
|
lName.sstr.cb = ((BPRELPTR32)pSym)->name[0];
|
||
|
if (SearchSym(&lName) != HR_found) {
|
||
|
goto ReturnNotFound;;
|
||
|
}
|
||
|
PopStack();
|
||
|
SetAddrSeg (&PTR_ADDR (pName->pv), 0);
|
||
|
if (((BPRELPTR32)pSym)->off != 0) {
|
||
|
|
||
|
SE_SetAddrOff(&PTR_ADDR (pName->pv), ((BPRELPTR32)pSym)->off);
|
||
|
|
||
|
ADDR_IS_OFF32 (PTR_ADDR (pName->pv)) = TRUE;
|
||
|
ADDR_IS_FLAT (PTR_ADDR (pName->pv)) = TRUE;
|
||
|
ADDR_IS_LI (PTR_ADDR (pName->pv)) = FALSE;
|
||
|
PTR_STYPE (pName->pv) = ((BPRELPTR32)pSym)->typind;
|
||
|
|
||
|
}
|
||
|
else {
|
||
|
goto ReturnNotFound;;
|
||
|
}
|
||
|
pExState->state.bprel = TRUE;
|
||
|
break;
|
||
|
|
||
|
case S_LDATA32:
|
||
|
case S_GDATA32:
|
||
|
case S_LTHREAD32:
|
||
|
case S_GTHREAD32:
|
||
|
lName.sstr.lpName = &((DATAPTR32)pSym)->name[1];
|
||
|
lName.sstr.cb = ((DATAPTR32)pSym)->name[0];
|
||
|
lrectyp = pSym->rectyp;
|
||
|
do {
|
||
|
if (SearchSym(&lName) != HR_found) {
|
||
|
goto ReturnNotFound;;
|
||
|
}
|
||
|
PopStack();
|
||
|
pSym = (SYMPTR)MHOmfLock(lName.hSym);
|
||
|
} while (pSym->rectyp != lrectyp);
|
||
|
pExState->state.fLData = TRUE;
|
||
|
SetAddrSeg (&PTR_ADDR (pName->pv), ((DATAPTR32)pSym)->seg);
|
||
|
|
||
|
SE_SetAddrOff(&PTR_ADDR (pName->pv), ((DATAPTR32)pSym)->off);
|
||
|
|
||
|
ADDR_IS_OFF32 (PTR_ADDR (pName->pv)) = TRUE;
|
||
|
ADDR_IS_FLAT (PTR_ADDR (pName->pv)) = TRUE;
|
||
|
ADDR_IS_LI (PTR_ADDR (pName->pv)) = TRUE;
|
||
|
PTR_STYPE (pName->pv) = ((DATAPTR32)pSym)->typind;
|
||
|
break;
|
||
|
|
||
|
case S_REGISTER:
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
DASSERT(FALSE);
|
||
|
break;
|
||
|
}
|
||
|
retval = HR_found;
|
||
|
|
||
|
ReturnNotFound:
|
||
|
pExState->state.fEProlog = savefEProlog;
|
||
|
return(retval);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/** SearchSym - search for symbol
|
||
|
|
||
|
* status = SearchSym (pName)
|
||
|
|
||
|
* Entry pName = structure describing state of search
|
||
|
* pName->CXTT = context to start search from
|
||
|
* pName->scope = mask that restricts search to specific scope
|
||
|
* pName->clsmask = mask for searching in classes.
|
||
|
|
||
|
* Typical entry values for specific kinds of search:
|
||
|
* Symbol Search (pName->initializer = INIT_sym):
|
||
|
* pName->sstr = symbol name
|
||
|
* pName->bn = based ptr to symbol node in the expr. tree
|
||
|
* pName->pfnCmp = ptr to "compare symbols" function
|
||
|
|
||
|
* Right Search (pName->initializer = INIT_right):
|
||
|
* (Searches for a symbol at the right of an operator like
|
||
|
* '::', '->' or '.')
|
||
|
* pName->sstr = symbol name
|
||
|
* pName->bn = based ptr to symbol node in the expr. tree
|
||
|
* pName->bnOp = based ptr to operator node
|
||
|
* pName->pfnCmp = ptr to "compare symbols" function
|
||
|
|
||
|
* Base Class Search (pName->initializer = INIT_base):
|
||
|
* (Looks for a base class, given the base class type --
|
||
|
* e.g., when casting a "Derived *" to a "Base *"
|
||
|
* pName->typeOut = Base class type
|
||
|
* pName->typeIn = Derived class type
|
||
|
* pName->pfnCmp = 0 (no comparison function needed)
|
||
|
|
||
|
* TypeDef Search (pName->initializer = INIT_tdef)
|
||
|
* (Looks for a UDT symbol of a given type)
|
||
|
* pName->typeIn = type of UDT to search for
|
||
|
* pName->pfnCmp = ptr to "compare typedef" funciton
|
||
|
|
||
|
* Qualified-Name Search (pName->initializer = INIT_qual)
|
||
|
* (Special kind of symbol search that looks for a qualified
|
||
|
* name)
|
||
|
* pName->sstr = symbol name
|
||
|
* pName->pfnCmp = ptr to "compare symbols" function
|
||
|
|
||
|
* Regular Expression Search (pName->initializer = INIT_RE)
|
||
|
* (Search for a symbol name that matches a reg. expression)
|
||
|
* pName->sstr = reg. expression
|
||
|
* pName->pfnCmp = ptr to "compare symbols" function
|
||
|
|
||
|
* Exit pName updated to reflect search results
|
||
|
* pName->hSym = handle of symbol
|
||
|
* pName->CXTT = context where symbol was found
|
||
|
* pName->pv = loaded symbol node
|
||
|
|
||
|
* Side-effects:
|
||
|
* (1) In all searches except typedef search the loaded
|
||
|
* symbol node is pushed on the stack. The caller should
|
||
|
* pop ST in case the push was unnecessary.
|
||
|
|
||
|
* (2) A tree rewrite may occur during a class search by
|
||
|
* inserting the "this" pointer in the expression tree, when
|
||
|
* the expression refers to a class member without naming
|
||
|
* the class explicitly. In that case HR_rewrite is returned.
|
||
|
|
||
|
* (3) A tree extension may occur during a class search in
|
||
|
* order to include a qualified expression for adjusting the
|
||
|
* this pointer during evaluation. (The tree extension is done
|
||
|
* by GenQualExpr, called by SearchClassName, and in that
|
||
|
* case the return value of SearchSym is HR_found.)
|
||
|
|
||
|
* (4) In both cases of tree rewrite and tree extension,the
|
||
|
* evaluation tree may be reallocated, rendering all non-based
|
||
|
* pointers to nodes invalid. Therefore the caller should
|
||
|
* not assume that the tree has not changed or moved, even
|
||
|
* if the return value of this function does not indicate
|
||
|
* a tree rewrite.
|
||
|
|
||
|
* Returns HR_error : error in search
|
||
|
* HR_notfound : symbol was not found
|
||
|
* HR_found : symbol was found
|
||
|
* HR_rewrite : symbol found but tree rewrite required
|
||
|
* HR_ambiguous: symbol found but ambiguous
|
||
|
* HR_end : end of search (indicates completion of
|
||
|
* adding symbols to the backpatch list while binding bp's)
|
||
|
|
||
|
*/
|
||
|
|
||
|
|
||
|
HR_t
|
||
|
SearchSym (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
CXT CXTTOut;
|
||
|
HSYM hSym = 0;
|
||
|
SCN_t retval;
|
||
|
|
||
|
// NOTE: this routine may be called recursively through MatchFunction
|
||
|
|
||
|
if ((hBPatch != 0) && (pExState->ambiguous != 0) &&
|
||
|
(pExState->ambiguous == pName->bn)) {
|
||
|
// this is a request for a symbol that was previously found to
|
||
|
// be ambiguous. Pop the next ambiguous symbol off the list and
|
||
|
// return it to the caller.
|
||
|
|
||
|
return ((HR_t) AmbFromList (pName));
|
||
|
}
|
||
|
|
||
|
if ((pName->sstr.cb == 1 ) &&
|
||
|
*(pName->sstr.lpName) == '.') {
|
||
|
|
||
|
|
||
|
EVAL_STATE( pName->pv ) = EV_rvalue;
|
||
|
EVAL_TYP( pName->pv ) = T_PCHAR;
|
||
|
EVAL_IS_PTR( pName->pv ) = TRUE;
|
||
|
EVAL_IS_CURPC( pName->pv ) = TRUE;
|
||
|
|
||
|
PushStack (pName->pv);
|
||
|
return (HR_found);
|
||
|
}
|
||
|
|
||
|
#if 0 // currently not use - be here in case of future needs
|
||
|
SearchWithSuffix = ( Suffix && !(((LPSSTR)pName)->searchmask & SSTR_RE) );
|
||
|
|
||
|
if ( SearchWithSuffix ) {
|
||
|
cbNew = cbOld+1;
|
||
|
memcpy( NameNew, NameOld, cbOld );
|
||
|
NameNew[ cbOld ] = Suffix;
|
||
|
NameNew[ cbNew ] = '\0';
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// this routine will terminate on the following conditions:
|
||
|
// 1. A symbol is found that is not a function address
|
||
|
// 2. A symbol is found that is a function and is not a method
|
||
|
// and the end of the symbol table is reached
|
||
|
// 3. A symbol is found that is a method and the end of the
|
||
|
// inheritance tree for the class is reached.
|
||
|
// If BindingBP is set, all function/method addresses that match
|
||
|
// the expression are entered into the TMList pointed to by pTMList
|
||
|
|
||
|
for (;;) {
|
||
|
switch (pName->state) {
|
||
|
case SYM_bclass:
|
||
|
// this state is a special entry for searching for the base
|
||
|
// class of a class when only the type of the base is known
|
||
|
|
||
|
if (InitMod (pName) == FALSE) {
|
||
|
// error in context
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
pName->state = SYM_class;
|
||
|
continue;
|
||
|
|
||
|
case SYM_init:
|
||
|
if (InitMod (pName) == FALSE) {
|
||
|
// error in context so we will allow check for registers
|
||
|
return ((HR_t) ParseRegister (pName));
|
||
|
}
|
||
|
if ((pName->scope & ~SCP_class) && *pName->sstr.lpName == '@') {
|
||
|
//search for @register, @linenumber, fastcall routine
|
||
|
|
||
|
if (_istdigit ((_TUCHAR)*(pName->sstr.lpName + 1))) {
|
||
|
return ((HR_t) LineNumber (pName));
|
||
|
}
|
||
|
else if ((hSym = PHFindNameInPublics (NULL,
|
||
|
pName->hExe, &pName->sstr, pExState->state.fCase,
|
||
|
pName->pfnCmp)) != 0) {
|
||
|
goto found;
|
||
|
}
|
||
|
else if (ParseRegister (pName) == HR_found) {
|
||
|
return (HR_found);
|
||
|
}
|
||
|
else {
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
}
|
||
|
else if (*pName->sstr.lpName == HSYM_MARKER) {
|
||
|
// search for handle to symbol. The handle to
|
||
|
// symbol comes from CV when a specific symbol
|
||
|
// is to be searched. The most common case is
|
||
|
// when a specific variable is to be displayed
|
||
|
// in the locals window
|
||
|
hSym = GetHSYMFromHSYMCode( (char *) pName->sstr.lpName + 1 );
|
||
|
DASSERT (hSym);
|
||
|
goto found;
|
||
|
}
|
||
|
// start normal symbol search
|
||
|
|
||
|
pName->state = SYM_lexical;
|
||
|
|
||
|
case SYM_lexical:
|
||
|
if (pName->scope & SCP_lexical) {
|
||
|
// search up the lexical scope to the function level
|
||
|
// but do not search the module level because of the
|
||
|
// class search required for method functions
|
||
|
|
||
|
while (!SHIsCXTMod (&pName->CXTT) ) {
|
||
|
if ((hSym = SHFindNameInContext (pName->hSym,
|
||
|
&pName->CXTT,
|
||
|
&pName->sstr,
|
||
|
pExState->state.fCase,
|
||
|
(PFNCMP) FNCMP,
|
||
|
&CXTTOut)) != 0) {
|
||
|
goto foundsave;
|
||
|
}
|
||
|
|
||
|
// go to the parent scope
|
||
|
|
||
|
SHGoToParent (&pName->CXTT, &CXTTOut);
|
||
|
// reset current symbol
|
||
|
pName->hSym = 0;
|
||
|
pName->CXTT = CXTTOut;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pName->state = SYM_class;
|
||
|
if (pName->scope & SCP_class) {
|
||
|
if (pName->ExpClass != 0) {
|
||
|
// search an explicit class
|
||
|
pName->CurClass = pName->ExpClass;
|
||
|
}
|
||
|
else if (ClassImp != 0) {
|
||
|
pName->CurClass = ClassImp;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
case SYM_class:
|
||
|
if ((pName->CurClass != 0) && (pName->scope & SCP_class)) {
|
||
|
retval = SearchClassName (pName);
|
||
|
switch (retval) {
|
||
|
case SCN_found:
|
||
|
// the symbol is a member of the class. If
|
||
|
// an explict class was not specified and
|
||
|
// the current context is implicitly a class,
|
||
|
// then we rewrote the tree to change the
|
||
|
// symbol reference to this->symbol
|
||
|
|
||
|
DASSERT (pName->hFound == 0);
|
||
|
DASSERT (pName->hAmbCl == 0);
|
||
|
if (EVAL_TYP (pName->pv) != T_NOTYPE) {
|
||
|
if (PushStack (pName->pv) == FALSE)
|
||
|
return (HR_error);
|
||
|
goto nopush;
|
||
|
}
|
||
|
else {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (HR_error);
|
||
|
}
|
||
|
|
||
|
case SCN_rewrite:
|
||
|
return (HR_rewrite);
|
||
|
|
||
|
case SCN_error:
|
||
|
return (HR_error);
|
||
|
|
||
|
default:
|
||
|
DASSERT (pName->hFound == 0);
|
||
|
DASSERT (pName->hAmbCl == 0);
|
||
|
if (pName->initializer == INIT_base) {
|
||
|
// we were searching for the base class of
|
||
|
// a class which was not found.
|
||
|
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
SHGetCxtFromHmod (pName->hMod, &pName->CXTT);
|
||
|
pName->hSym = 0;
|
||
|
pName->state = SYM_module;
|
||
|
|
||
|
case SYM_module:
|
||
|
if (pName->scope & SCP_module) {
|
||
|
if ((hSym = SHFindNameInContext (pName->hSym,
|
||
|
&pName->CXTT,
|
||
|
&pName->sstr,
|
||
|
pExState->state.fCase,
|
||
|
pName->pfnCmp,
|
||
|
&CXTTOut)) != 0)
|
||
|
{
|
||
|
goto foundsave;
|
||
|
}
|
||
|
}
|
||
|
pName->state = SYM_global;
|
||
|
pName->hSym = 0;
|
||
|
|
||
|
case SYM_global:
|
||
|
// users specified a context on a break point command
|
||
|
// we have already searched the module specified so end the search
|
||
|
// here
|
||
|
// sps - 7/24/92
|
||
|
if (pBindBPCxt && pBindBPCxt->hMod &&(pBindBPCxt->hMod != pName->hModCur) &&
|
||
|
(pExState->ambiguous != 0) && (pExState->ambiguous == pName->bn)) {
|
||
|
|
||
|
return(HR_end);
|
||
|
}
|
||
|
|
||
|
// search global symbol table
|
||
|
if (pName->scope & SCP_global) {
|
||
|
|
||
|
if ((hSym = SHFindNameInTypes (&pName->CXTT,
|
||
|
&pName->sstr, pExState->state.fCase, pName->pfnCmp,
|
||
|
&CXTTOut)) != 0) {
|
||
|
goto foundsave;
|
||
|
}
|
||
|
|
||
|
if ((hSym = SHFindNameInGlobal (pName->hSym,
|
||
|
&pName->CXTT,
|
||
|
&pName->sstr,
|
||
|
pExState->state.fCase,
|
||
|
pName->pfnCmp,
|
||
|
&CXTTOut)) != 0)
|
||
|
{
|
||
|
goto foundsave;
|
||
|
}
|
||
|
}
|
||
|
pName->hModCur = SHGetNextMod (pName->hExe, pName->hMod);
|
||
|
pName->hSym = 0;
|
||
|
pName->state = SYM_exe;
|
||
|
|
||
|
case SYM_exe:
|
||
|
if (pName->scope & SCP_global) {
|
||
|
#ifdef LOADALL
|
||
|
do {
|
||
|
SHGetCxtFromHmod (pName->hModCur, &pName->CXTT);
|
||
|
if ((hSym = SHFindNameInContext (pName->hSym,
|
||
|
&pName->CXTT,
|
||
|
&pName->sstr,
|
||
|
pExState->state.fCase,
|
||
|
pName->pfnCmp,
|
||
|
&CXTTOut)) != 0)
|
||
|
{
|
||
|
goto foundsave;
|
||
|
}
|
||
|
} while (pName->hSym = 0,
|
||
|
(pName->hModCur = SHGetNextMod (pName->hExe,
|
||
|
pName->hModCur)) != pName->hMod);
|
||
|
#else
|
||
|
pName->CXTT.hGrp = pName->CXTT.hMod;
|
||
|
pName->CXTT.hMod = 0;
|
||
|
if ((hSym = SHFindNameInContext (pName->hSym,
|
||
|
&pName->CXTT,
|
||
|
&pName->sstr,
|
||
|
pExState->state.fCase,
|
||
|
pName->pfnCmp,
|
||
|
&CXTTOut) ) != 0)
|
||
|
{
|
||
|
|
||
|
goto foundsave;
|
||
|
}
|
||
|
pName->CXTT.hMod = pName->CXTT.hGrp;
|
||
|
#endif
|
||
|
}
|
||
|
// we are at the end of the normal symbol search. If the
|
||
|
// symbol has not been found, we will search the public
|
||
|
// symbol table.
|
||
|
|
||
|
if (!BindingBP) {
|
||
|
// if we are not binding breakpoints and we have
|
||
|
// found a symbol in previous calls, return. Otherwise,
|
||
|
// we will look in the publics table. Note that
|
||
|
// finding a symbol in the publics table has a
|
||
|
// large probability of finding one with a type of
|
||
|
// zero which will limit it's usefulness
|
||
|
|
||
|
if (pName->hSym != 0) {
|
||
|
if (pName->possibles > 1) {
|
||
|
pExState->err_num = ERR_AMBIGUOUS;
|
||
|
return (HR_ambiguous);
|
||
|
}
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
// we are binding breakpoints. We need to see if
|
||
|
// one or more symbols have matched. If so, we
|
||
|
// are done with the symbol search. If we have
|
||
|
// not found the symbol, we search the publics table.
|
||
|
// For breakpoints, we do not need type information,
|
||
|
// only the address, so symbols found in the publics
|
||
|
// table are much more useful.
|
||
|
|
||
|
if ((pExState->ambiguous != 0) &&
|
||
|
(pExState->ambiguous == pName->bn)) {
|
||
|
// we have found at least one symbol to this
|
||
|
// point. this is indicated by SymAmbToList
|
||
|
// setting the node of the function's symbol
|
||
|
// into the expression state structure. By
|
||
|
// this point all ambiguous symbols have been
|
||
|
// added to the back patch list. If we have
|
||
|
// not found any symbol yet, we search the
|
||
|
// publics table. Note also that there cannot
|
||
|
// be any ambiguity in the publics table because
|
||
|
// the function names have to be unique in the
|
||
|
// publics table.
|
||
|
|
||
|
return (HR_end);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// search public symbol table
|
||
|
pName->state = SYM_public;
|
||
|
|
||
|
case SYM_public:
|
||
|
// some searches such as finding a UDT by type
|
||
|
// do not require a symbol
|
||
|
if (pName->scope & SCP_global) {
|
||
|
hSym = PHFindNameInPublics (NULL,
|
||
|
pName->hExe,
|
||
|
&pName->sstr,
|
||
|
pExState->state.fCase,
|
||
|
pName->pfnCmp);
|
||
|
if (!hSym) {
|
||
|
unsigned char oldmask = pName->sstr.searchmask;
|
||
|
pName->sstr.searchmask |= SSTR_FuzzyPublic;
|
||
|
pName->sstr.searchmask |= SSTR_NoHash;
|
||
|
hSym = PHFindNameInPublics (NULL,
|
||
|
pName->hExe,
|
||
|
&pName->sstr,
|
||
|
pExState->state.fCase,
|
||
|
pName->pfnCmp);
|
||
|
pName->sstr.searchmask = oldmask;
|
||
|
}
|
||
|
if (hSym != 0) {
|
||
|
if (hSym == pName->hSym) {
|
||
|
// We found this symbol last call! There
|
||
|
// are no more to be found (or worth finding).
|
||
|
return HR_notfound;
|
||
|
}
|
||
|
|
||
|
// What's this all about???? BryanT 3/11/96
|
||
|
if ((TargetMachine == mptmips) ||
|
||
|
(TargetMachine == mptdaxp))
|
||
|
{
|
||
|
goto found;
|
||
|
} else {
|
||
|
goto foundsave;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (EVAL_IS_REG (pName->pv)) {
|
||
|
return (HR_notfound); // found it last time - quit looking
|
||
|
}
|
||
|
else if ((pName->scope & ~SCP_class) && ParseRegister (pName) == HR_found) {
|
||
|
return (HR_found);
|
||
|
}
|
||
|
ErrUnknownSymbol(&pName->sstr);
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
foundsave:
|
||
|
EVAL_CXTT(pName->pv) = pName->CXTT = CXTTOut;
|
||
|
found:
|
||
|
pName->hSym = hSym;
|
||
|
EVAL_HSYM (pName->pv) = pName->hSym;
|
||
|
#ifdef NEVER
|
||
|
if (pName->initializer == INIT_tdef) {
|
||
|
// the routines that search for UDTs only need the
|
||
|
// hsym and the stack pointer may not be valid at this
|
||
|
// point (FormatUDT for example), so return now
|
||
|
|
||
|
return (HR_found);
|
||
|
}
|
||
|
#endif
|
||
|
if (SymToNode (pName) == FALSE) {
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
|
||
|
#ifdef NEVER
|
||
|
|
||
|
// This is now handled by SetNodeType
|
||
|
|
||
|
if (EVAL_IS_PTR(pName->pv) &&
|
||
|
(EVAL_PTRTYPE(pName->pv) >= CV_PTR_BASE_VAL) &&
|
||
|
(EVAL_PTRTYPE(pName->pv) <= CV_PTR_BASE_SEGADDR)){
|
||
|
if (SearchBasePtrBase(pName) != HR_found) {
|
||
|
return(HR_notfound);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (PushStack (pName->pv) == FALSE)
|
||
|
return (HR_error);
|
||
|
nopush:
|
||
|
if (!EVAL_IS_FCN (ST)) {
|
||
|
// if this symbol is not a function and we have not processed
|
||
|
// a function previously, then the search is done
|
||
|
|
||
|
if (pExState->ambiguous == 0) {
|
||
|
return (HR_found);
|
||
|
}
|
||
|
else if (pExState->ambiguous == pName->bn) {
|
||
|
pExState->err_num = ERR_SYMCONFLICT;
|
||
|
return (HR_error);
|
||
|
}
|
||
|
else {
|
||
|
return (HR_found);
|
||
|
}
|
||
|
}
|
||
|
else if (EVAL_IS_METHOD (ST)) {
|
||
|
// ambiguous methods were entered into the ambiguous breakpoint
|
||
|
// list by SetBPValue which was called in SearchClassName
|
||
|
|
||
|
return (HR_found);
|
||
|
}
|
||
|
else if (pName->state == SYM_public) {
|
||
|
// we will take the first function symbol found in the
|
||
|
// publics table since the names have to be unique in the
|
||
|
// publics table
|
||
|
|
||
|
return (HR_found);
|
||
|
}
|
||
|
else if ((BindingBP == TRUE) && (bArgList == 0)) {
|
||
|
// if we are binding breakpoints and there is not an
|
||
|
// argument list, we will enter all functions found with
|
||
|
// this name into the breakpoint ambiguity list.
|
||
|
|
||
|
return (SymAmbToList (pName));
|
||
|
}
|
||
|
else {
|
||
|
// the found symbol is non-member function. Continue
|
||
|
// search to end of symbols to find the best function.
|
||
|
// in the case of a breakpoint with argument list, there
|
||
|
// must be an exact match on the argument types
|
||
|
|
||
|
EVAL_MOD (pName->pv) = SHHMODFrompCXT (&pName->CXTT);
|
||
|
|
||
|
if (pName->scope & SCP_nomatchfn)
|
||
|
return (HR_found);
|
||
|
|
||
|
return (MatchFunction (pName));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
bool_t
|
||
|
InitMod (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
if (((pName->hMod = SHHMODFrompCXT (&pName->CXTT)) == 0) ||
|
||
|
((pName->hExe = SHHexeFromHmod (pName->hMod)) == 0)) {
|
||
|
// error in context
|
||
|
return (FALSE);
|
||
|
}
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Class searching and main support routines
|
||
|
|
||
|
/*** SearchClassName - Search a class and bases for element by name
|
||
|
|
||
|
* flag = SearchClassName (pName)
|
||
|
|
||
|
* Entry pName = pointer to struct describing search
|
||
|
|
||
|
* Exit pName updated to reflect type
|
||
|
|
||
|
* Returns SCN_... enum describing result
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
SearchClassName (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
SCN_t retval;
|
||
|
ulong max;
|
||
|
CV_fldattr_t attr = {0};
|
||
|
|
||
|
// allocate and initialize list of dominated virtual bases
|
||
|
|
||
|
if (hVBDom == 0) {
|
||
|
if ((hVBDom = MemAllocate (sizeof (dombase_t) +
|
||
|
DOMBASE_DEFAULT * sizeof (CV_typ_t))) == 0) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pVBDom = (pdombase_t) MemLock (hVBDom);
|
||
|
pVBDom->MaxIndex = DOMBASE_DEFAULT;
|
||
|
}
|
||
|
else {
|
||
|
pVBDom = (pdombase_t) MemLock (hVBDom);
|
||
|
}
|
||
|
pVBDom->CurIndex = 0;
|
||
|
|
||
|
// allocate and initialize list of searched virtual bases
|
||
|
|
||
|
if (hVBSearch == 0) {
|
||
|
if ((hVBSearch = MemAllocate (sizeof (dombase_t) +
|
||
|
DOMBASE_DEFAULT * sizeof (CV_typ_t))) == 0) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
MemUnLock (hVBDom);
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pVBSearch = (pdombase_t) MemLock (hVBSearch);
|
||
|
pVBSearch->MaxIndex = DOMBASE_DEFAULT;
|
||
|
}
|
||
|
else {
|
||
|
pVBSearch = (pdombase_t) MemLock (hVBSearch);
|
||
|
}
|
||
|
pVBSearch->CurIndex = 0;
|
||
|
|
||
|
// allocate and initialize structure for recursive base searches
|
||
|
|
||
|
if (hSymClass == 0) {
|
||
|
if ((hSymClass = MemAllocate (sizeof (symclass_t) +
|
||
|
SYMBASE_DEFAULT * sizeof (symbase_t))) == 0) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
MemUnLock (hVBDom);
|
||
|
MemUnLock (hVBSearch);
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pSymClass = (psymclass_t) MemLock (hSymClass);
|
||
|
pSymClass->MaxIndex = SYMBASE_DEFAULT;
|
||
|
}
|
||
|
else {
|
||
|
pSymClass = (psymclass_t) MemLock (hSymClass);
|
||
|
}
|
||
|
pSymClass->CurIndex = 0;
|
||
|
pSymClass->hNext = 0;
|
||
|
max = pSymClass->MaxIndex;
|
||
|
memset (pSymClass, 0, max * sizeof (symbase_t) + sizeof (symclass_t));
|
||
|
pSymClass->MaxIndex = max;
|
||
|
|
||
|
// recurse through the inheritance tree searching for the feature
|
||
|
|
||
|
if ((retval = RecurseBase (pName, pName->CurClass, 0, 0, 0,
|
||
|
attr, FALSE)) != SCN_error) {
|
||
|
// at this point we need to check for dominance and then clean
|
||
|
// up the allocated memory and return the search results
|
||
|
|
||
|
if (pName->possibles == 0) {
|
||
|
// if the count was zero, the handle of found list must be zero
|
||
|
DASSERT (pName->hFound == 0);
|
||
|
retval = SCN_notfound;
|
||
|
}
|
||
|
else if (pName->cFound == 0) {
|
||
|
if (pName->hFound == 0) {
|
||
|
DASSERT (pSymClass->viable == TRUE);
|
||
|
// the found value is in the permanent stack. This means
|
||
|
// the feature was found in the most derived class
|
||
|
retval = SetValue (pName);
|
||
|
}
|
||
|
}
|
||
|
else if (pName->cFound == 1) {
|
||
|
// the feature was not found in the most derived class
|
||
|
// but no other matching feature was found. Move the feature
|
||
|
// descriptor pointed to by pName->hFound into the permanent
|
||
|
// feature descriptor pSymClass. An important thing to remember
|
||
|
// here is that there can only be one feature descriptor pSymClass
|
||
|
// when calling SetValue unless we are binding breakpoints.
|
||
|
// If we are binding breakpoints we can have multiple feature
|
||
|
// descriptors in pSymClass and the list pointed to by
|
||
|
// pName->hAmbCl. If we have an argument list, these must
|
||
|
// resolve to one feature. If we do not have an argument
|
||
|
// list, all of the features are valid and must be added
|
||
|
// to the breakpoint list.
|
||
|
|
||
|
MoveSymCl (pName->hFound);
|
||
|
pName->hFound = 0;
|
||
|
pName->cFound--;
|
||
|
DASSERT (pSymClass->viable == TRUE);
|
||
|
retval = SetValue (pName);
|
||
|
}
|
||
|
else {
|
||
|
// since two or more features were found, we need to cull the
|
||
|
// feature list to remove dominated features and features which
|
||
|
// are the same static item. Ambiguity is removed strictly on
|
||
|
// the name of the feature. Overloaded methods are resolved later.
|
||
|
|
||
|
if ((retval = RemoveAmb (pName)) == SCN_found) {
|
||
|
retval = SetValue (pName);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
MemUnLock (hVBDom);
|
||
|
MemUnLock (hVBSearch);
|
||
|
MemUnLock (hSymClass);
|
||
|
DASSERT (pName->hAmbCl == 0);
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** RecurseBase - Search a class and its bases for element by name
|
||
|
|
||
|
* status = RecurseBase (pName, type, vbptr, vbpoff, thisadjust, attr, virtual)
|
||
|
|
||
|
* Entry pName = pointer to struct describing search
|
||
|
* type = type index of class
|
||
|
* vbptr = type index of virtual base pointer
|
||
|
* vbpoff = offset of virtual base pointer from address point
|
||
|
* thisadjust = offset of base from previous class
|
||
|
* thisadjust = virtual base index if virtual base
|
||
|
* attr = attribute of base class
|
||
|
* virtual = TRUE if this is a virtual base
|
||
|
|
||
|
* Exit pName updated to reflect type
|
||
|
|
||
|
* Returns SCN_... enum describing result
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
RecurseBase (
|
||
|
psearch_t pName,
|
||
|
CV_typ_t type,
|
||
|
CV_typ_t vbptr,
|
||
|
UOFFSET vbpoff,
|
||
|
UOFFSET thisadjust,
|
||
|
CV_fldattr_t attr,
|
||
|
bool_t fVirtual
|
||
|
)
|
||
|
{
|
||
|
SCN_t retval;
|
||
|
|
||
|
// save offset of base from address point for this pointer adjustment
|
||
|
|
||
|
if (SetBase (pName, type, vbptr, vbpoff, thisadjust, attr, fVirtual) != SCN_found) {
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
if (pName->initializer == INIT_base) {
|
||
|
retval = SearchBType (pName);
|
||
|
}
|
||
|
else if (pName->initializer == INIT_AErule ) {
|
||
|
retval = SearchAERule (pName);
|
||
|
}
|
||
|
else {
|
||
|
retval = SearchRoot (pName);
|
||
|
}
|
||
|
switch (retval) {
|
||
|
case SCN_found:
|
||
|
if (((pName->clsmask & CLS_virtintro) == FALSE) &&
|
||
|
(pName->initializer != INIT_AErule)) {
|
||
|
// add virtual bases to searched and dominated base lists
|
||
|
// if we were searching for the introducing virtual function or auto-expand
|
||
|
// class name the fact that we found one is sufficient.
|
||
|
|
||
|
if ((pSymClass->isvbase == TRUE) &&
|
||
|
(VBaseFound (pName) == TRUE)) {
|
||
|
// the found feature is a previously found
|
||
|
// virtual base class.
|
||
|
|
||
|
pSymClass->isdupvbase = TRUE;
|
||
|
}
|
||
|
if ((retval = AddVBList
|
||
|
(pSymClass, &pVBSearch, &hVBSearch)) != SCN_error) {
|
||
|
retval = AddVBList (pSymClass, &pVBDom, &hVBDom);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
case SCN_error:
|
||
|
return (retval);
|
||
|
|
||
|
case SCN_notfound:
|
||
|
// we did not find the element in the root of this class
|
||
|
// so we search the inheritance tree.
|
||
|
|
||
|
if (pExState->state.fSupBase == FALSE) {
|
||
|
return (SearchBases (pName));
|
||
|
}
|
||
|
else {
|
||
|
return (SCN_notfound);
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** VBaseFound - search to see if virtual base already found
|
||
|
|
||
|
* status = VBaseFound (pName)
|
||
|
|
||
|
* Entry pName = structure describing search
|
||
|
* pSymClass = structure describing most recent class search
|
||
|
|
||
|
* Exit pName updated to reflect search
|
||
|
* pSymClass updated to unambiguous feature
|
||
|
|
||
|
* Returns TRUE if duplicate virtual base found
|
||
|
* FALSE if not duplicate virtual base
|
||
|
*/
|
||
|
|
||
|
|
||
|
bool_t
|
||
|
VBaseFound (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
psymclass_t pSymCl;
|
||
|
HDEP hSymCl;
|
||
|
CV_typ_t type = EVAL_TYP (&pSymClass->evalP);
|
||
|
|
||
|
hSymCl = pName->hFound;
|
||
|
while (hSymCl != 0) {
|
||
|
pSymCl = (psymclass_t) MemLock (hSymCl);
|
||
|
if (pSymCl == pSymClass) {
|
||
|
return (FALSE);
|
||
|
}
|
||
|
if ((pSymCl->isvbase == TRUE) && (type == EVAL_TYP (&pSymCl->evalP))) {
|
||
|
// the virtual base is already in the list
|
||
|
return (TRUE);
|
||
|
}
|
||
|
}
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/** RemoveAmb - remove ambiguity
|
||
|
|
||
|
* status = RemoveAmb (pName)
|
||
|
|
||
|
* Entry pName = structure describing search
|
||
|
* pSymClass = structure describing most recent class search
|
||
|
|
||
|
* Exit pName updated to reflect search
|
||
|
* pSymClass updated to unambiguous feature
|
||
|
|
||
|
* Returns SCN_found if unambiguous feature found
|
||
|
* SCN_error otherwise
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
RemoveAmb (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
psymclass_t pSymCl;
|
||
|
|
||
|
// we know that at this point two or more features were found
|
||
|
// the list of features are pointed to by pName->hFound.
|
||
|
// The permanent stack cannot contain a viable feature
|
||
|
|
||
|
DASSERT (pSymClass->viable == FALSE);
|
||
|
MoveSymCl (pName->hFound);
|
||
|
pName->hFound = pSymClass->hNext;
|
||
|
while (pName->hFound != 0) {
|
||
|
// lock and check next list element
|
||
|
|
||
|
pSymCl = (psymclass_t) MemLock (pName->hFound);
|
||
|
switch (IsDominated (pSymClass, pSymCl)) {
|
||
|
case DOM_ambiguous:
|
||
|
// the new feature does not dominate the current best
|
||
|
MemUnLock (pName->hFound);
|
||
|
if (BindingBP == FALSE) {
|
||
|
pExState->err_num = ERR_AMBIGUOUS;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
// feature is ambiguous and we are setting breakpoints
|
||
|
// save the feature in the ambiguous list and advance to
|
||
|
// the next feature
|
||
|
|
||
|
pSymClass->hNext = pSymCl->hNext;
|
||
|
pSymCl->hNext = pName->hAmbCl;
|
||
|
pName->hAmbCl = pName->hFound;
|
||
|
MemUnLock (pName->hAmbCl);
|
||
|
pName->hFound = pSymClass->hNext;
|
||
|
break;
|
||
|
|
||
|
case DOM_replace:
|
||
|
// decrement the number of possible matches by the
|
||
|
// count in the current best structure
|
||
|
|
||
|
pName->possibles -= pSymClass->possibles;
|
||
|
pName->cFound--;
|
||
|
MemUnLock (pName->hFound);
|
||
|
MoveSymCl (pName->hFound);
|
||
|
pName->hFound = pSymClass->hNext;
|
||
|
PurgeAmbCl (pName);
|
||
|
break;
|
||
|
|
||
|
case DOM_keep:
|
||
|
// decrement the number of possible matches by the
|
||
|
// count in the structure being discarded
|
||
|
|
||
|
pName->possibles -= pSymCl->possibles;
|
||
|
pName->cFound--;
|
||
|
pSymClass->hNext = pSymCl->hNext;
|
||
|
MemUnLock (pName->hFound);
|
||
|
pName->hFound = pSymClass->hNext;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// decrement the count of found features to account for the one we kept
|
||
|
pName->cFound--;
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*** SearchBases - Search for an element in the bases of a class
|
||
|
|
||
|
* flag = SearchBases (pName, pvClass)
|
||
|
|
||
|
* Entry pName = pointer to struct describing search
|
||
|
|
||
|
* Exit pName updated to reflect type
|
||
|
|
||
|
* Returns enum describing search state
|
||
|
|
||
|
*/
|
||
|
|
||
|
SCN_t
|
||
|
SearchBases (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
ulong cnt; // count of number of elements in struct
|
||
|
HTYPE hField; // handle to type record for struct field list
|
||
|
char *pField; // pointer to field list
|
||
|
uint fSkip = 0; // offset in the field list
|
||
|
SCN_t retval = SCN_notfound;
|
||
|
CV_typ_t newindex;
|
||
|
CV_typ_t vbptr;
|
||
|
UOFFSET offset;
|
||
|
UOFFSET vbpoff;
|
||
|
CV_fldattr_t attr;
|
||
|
CV_fldattr_t vattr;
|
||
|
peval_t pvBase = &pSymClass->symbase[pSymClass->CurIndex].Base;
|
||
|
bool_t fVirtual;
|
||
|
|
||
|
// Set to head of type record and search the base classes in order
|
||
|
|
||
|
if ((hField = THGetTypeFromIndex (EVAL_MOD (pvBase), CLASS_FIELD (pvBase))) == 0) {
|
||
|
// set error and stop search
|
||
|
DASSERT (FALSE);
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
|
||
|
for (cnt = CLASS_COUNT (pvBase); cnt > 0; cnt--) {
|
||
|
fSkip += SkipPad(((uchar *)pField) + fSkip);
|
||
|
newindex = 0;
|
||
|
switch (((plfEasy)(pField + fSkip))->leaf) {
|
||
|
case LF_INDEX:
|
||
|
// switch to next part of type record
|
||
|
newindex = ((plfIndex)(pField + fSkip))->index;
|
||
|
MHOmfUnLock (hField);
|
||
|
if ((hField = THGetTypeFromIndex (EVAL_MOD (pvBase), newindex)) == 0) {
|
||
|
DASSERT (FALSE);
|
||
|
pExState->err_num = ERR_INTERNAL;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
fSkip = 0;
|
||
|
// the LF_INDEX is not part of the field count
|
||
|
cnt++;
|
||
|
break;
|
||
|
|
||
|
case LF_BCLASS:
|
||
|
// read type index of base class offset of base pointer
|
||
|
// from address point
|
||
|
|
||
|
attr = ((plfBClass)(pField + fSkip))->attr;
|
||
|
newindex = ((plfBClass)(pField + fSkip))->index;
|
||
|
fSkip += sizeof (struct lfBClass);
|
||
|
offset = (UOFFSET)RNumLeaf (pField + fSkip, &fSkip);
|
||
|
vbptr = 0;
|
||
|
vbpoff = 0;
|
||
|
fVirtual = FALSE;
|
||
|
goto foo;
|
||
|
|
||
|
case LF_VBCLASS:
|
||
|
// read type index of base class, type index of virtual
|
||
|
// base pointer, offset of virtual base pointer from
|
||
|
// address point and offset of virtual base displacement
|
||
|
// from virtual base table
|
||
|
|
||
|
vattr = ((plfVBClass)(pField + fSkip))->attr;
|
||
|
newindex = ((plfVBClass)(pField + fSkip))->index;
|
||
|
vbptr = ((plfVBClass)(pField + fSkip))->vbptr;
|
||
|
fVirtual = TRUE;
|
||
|
fSkip += sizeof (struct lfVBClass);
|
||
|
vbpoff = (UOFFSET)RNumLeaf (pField + fSkip, &fSkip);
|
||
|
offset = (UOFFSET)RNumLeaf (pField + fSkip, &fSkip);
|
||
|
if ((pName->clsmask & CLS_virtintro) == FALSE) {
|
||
|
// if we are searching for the introducing virtual method
|
||
|
// then we want to search all bases
|
||
|
if (VBSearched (newindex) == TRUE) {
|
||
|
break;
|
||
|
}
|
||
|
retval = AddVBType (&pVBSearch, &hVBSearch, newindex);
|
||
|
}
|
||
|
|
||
|
foo:
|
||
|
// check base class
|
||
|
|
||
|
MHOmfUnLock (hField);
|
||
|
|
||
|
// Advance to next base class structure
|
||
|
|
||
|
if (IncrSymBase () != SCN_found) {
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
retval = RecurseBase (pName, newindex, vbptr, vbpoff, offset, attr, fVirtual);
|
||
|
switch (retval) {
|
||
|
case SCN_error:
|
||
|
// if we got an error, abort the search
|
||
|
newindex = 0;
|
||
|
break;
|
||
|
|
||
|
case SCN_found:
|
||
|
// we have found the feature in a base class.
|
||
|
// Dup the class search structure and continue the
|
||
|
// search to the end of the inheritance tree
|
||
|
|
||
|
if ((pName->clsmask & CLS_virtintro) == FALSE &&
|
||
|
(pName->initializer != INIT_AErule))
|
||
|
{
|
||
|
if ((retval = DupSymCl (pName)) != SCN_found) {
|
||
|
// if we got an error duping, abort the search
|
||
|
newindex = 0;
|
||
|
}
|
||
|
// set not found, so the unwinding of the call stack
|
||
|
// does not reduplicate the class search structure
|
||
|
retval = SCN_notfound;
|
||
|
}
|
||
|
else {
|
||
|
// we were searching for the introducing virtual
|
||
|
// method. Since there can be only one in the
|
||
|
// tree above the virtual method, we can terminate
|
||
|
// the search immediately Or we are searching for a
|
||
|
// class to autoexpand the node. The first match we found is
|
||
|
// what we will use in this case.
|
||
|
return (retval);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
pSymClass->CurIndex--;
|
||
|
MHOmfLock (hField);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
// we have reached the end of the base classes.
|
||
|
// exit loop and check search results.
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
if (newindex == 0) {
|
||
|
// all base classes must appear first in the field list.
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
MHOmfUnLock (hField);
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*** SearchBType - Search for an base by type
|
||
|
|
||
|
* flag = SearchBType (pName)
|
||
|
|
||
|
* Entry pName = pointer to struct describing search
|
||
|
* pSymClass = pointer to base class path list structure
|
||
|
|
||
|
* Exit pName updated to reflect search
|
||
|
|
||
|
* Return enum describing search
|
||
|
|
||
|
* If the base class is found, the base class value is stored in the
|
||
|
* the symbase[], not in pSymClass->evalP. This is to simplify the
|
||
|
* GenQualExpr code.
|
||
|
*/
|
||
|
|
||
|
|
||
|
INLINE BOOL
|
||
|
getBaseDefnFromDecl(
|
||
|
CV_typ_t typeIn,
|
||
|
peval_t pv,
|
||
|
CV_typ_t* ptypeOut
|
||
|
)
|
||
|
{
|
||
|
peval_t pvBase = &pSymClass->symbase[pSymClass->CurIndex].Base;
|
||
|
Unreferenced (pv);
|
||
|
return getDefnFromDecl (typeIn, pvBase, ptypeOut);
|
||
|
}
|
||
|
|
||
|
bool_t
|
||
|
getDefnFromDecl(
|
||
|
CV_typ_t typeIn,
|
||
|
peval_t pv,
|
||
|
CV_typ_t* ptypeOut
|
||
|
)
|
||
|
{
|
||
|
HTYPE hType;
|
||
|
uint skip;
|
||
|
TYPPTR pType;
|
||
|
eval_t localEval;
|
||
|
neval_t nv = &localEval;
|
||
|
*nv = *pv;
|
||
|
|
||
|
DASSERT (!CV_IS_PRIMITIVE (typeIn));
|
||
|
if ((hType = THGetTypeFromIndex (EVAL_MOD (nv), typeIn)) == 0) {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return FALSE;
|
||
|
}
|
||
|
pType = (TYPPTR)MHOmfLock(hType);
|
||
|
|
||
|
switch (pType->leaf) {
|
||
|
case LF_STRUCTURE:
|
||
|
case LF_CLASS:
|
||
|
{
|
||
|
plfClass pClass = (plfClass)(&pType->leaf);
|
||
|
if (pClass->property.fwdref) {
|
||
|
skip = offsetof (lfClass, data);
|
||
|
RNumLeaf (((char *)(&pClass->leaf)) + skip, &skip);
|
||
|
// forward ref - look for the definition of the UDT
|
||
|
if ((*ptypeOut = GetUdtDefnTindex (typeIn, nv, ((char *)&(pClass->leaf)) + skip)) == T_NOTYPE) {
|
||
|
goto failed;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
*ptypeOut = typeIn;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case LF_UNION:
|
||
|
{
|
||
|
plfUnion pUnion = (plfUnion)(&pType->leaf);
|
||
|
if (pUnion->property.fwdref) {
|
||
|
skip = offsetof (lfUnion, data);
|
||
|
RNumLeaf (((char *)(&pUnion->leaf)) + skip, &skip);
|
||
|
// forward ref - look for the definition of the UDT
|
||
|
if ((*ptypeOut = GetUdtDefnTindex (typeIn, nv, ((char *)&(pUnion->leaf)) + skip)) == T_NOTYPE) {
|
||
|
goto failed;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
*ptypeOut = typeIn;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case LF_ENUM:
|
||
|
{
|
||
|
plfEnum pEnum = (plfEnum)(&pType->leaf);
|
||
|
if (pEnum->property.fwdref) {
|
||
|
// forward ref - look for the definition of the UDT
|
||
|
if ((*ptypeOut = GetUdtDefnTindex (typeIn, nv, (char *) pEnum->Name)) == T_NOTYPE) {
|
||
|
goto failed;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
*ptypeOut = typeIn;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
*ptypeOut = typeIn;
|
||
|
}
|
||
|
|
||
|
MHOmfUnLock (hType);
|
||
|
return TRUE;
|
||
|
|
||
|
failed:
|
||
|
MHOmfUnLock (hType);
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
SCN_t
|
||
|
SearchBType (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
ulong cnt; // count of number of elements in struct
|
||
|
HTYPE hField; // handle to type record for struct field list
|
||
|
char *pField; // pointer to field list
|
||
|
uint fSkip = 0; // offset in the field list
|
||
|
ulong anchor = 0; // offset in the field list to start of type
|
||
|
CV_typ_t newindex;
|
||
|
CV_typ_t vbptr;
|
||
|
SCN_t retval = SCN_notfound;
|
||
|
UOFFSET offset;
|
||
|
UOFFSET vbpoff;
|
||
|
bool_t termflag = FALSE;
|
||
|
CV_fldattr_t attr;
|
||
|
CV_fldattr_t vattr;
|
||
|
peval_t pvBase = &pSymClass->symbase[pSymClass->CurIndex].Base;
|
||
|
|
||
|
// set hField to the handle of the field list for the class
|
||
|
|
||
|
if ((hField = THGetTypeFromIndex (EVAL_MOD (pvBase), CLASS_FIELD (pvBase))) == 0) {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
|
||
|
// walk field list for the class
|
||
|
|
||
|
for (cnt = CLASS_COUNT (pvBase); cnt > 0; cnt--) {
|
||
|
fSkip += SkipPad(((uchar *)pField) + fSkip);
|
||
|
switch (((plfEasy)(pField + fSkip))->leaf) {
|
||
|
case LF_INDEX:
|
||
|
// switch to new type record because compiler split it up
|
||
|
newindex = ((plfIndex)(pField + fSkip))->index;
|
||
|
MHOmfUnLock (hField);
|
||
|
if ((hField = THGetTypeFromIndex (EVAL_MOD (pvBase), newindex)) == 0) {
|
||
|
pExState->err_num = ERR_INTERNAL;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
fSkip = 0;
|
||
|
// the LF_INDEX is not part of the field count
|
||
|
cnt++;
|
||
|
break;
|
||
|
|
||
|
case LF_BCLASS:
|
||
|
attr = ((plfBClass)(pField + fSkip))->attr;
|
||
|
if (!getBaseDefnFromDecl(((plfBClass)(pField + fSkip))->index, pName->pv, &newindex))
|
||
|
return SCN_error;
|
||
|
fSkip += offsetof (lfBClass, offset);
|
||
|
offset = (UOFFSET)RNumLeaf (pField + fSkip, &fSkip);
|
||
|
if (pName->typeOut == newindex) {
|
||
|
// base has been found, set result values
|
||
|
|
||
|
MHOmfUnLock (hField);
|
||
|
if (IncrSymBase () != SCN_found) {
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
|
||
|
// save offset of base from address point for this
|
||
|
// pointer adjustment
|
||
|
|
||
|
if (SetBase (pName, newindex, 0, 0, offset, attr, FALSE) != SCN_found) {
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pSymClass->viable = TRUE;
|
||
|
pName->possibles++;
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LF_VBCLASS:
|
||
|
vattr = ((plfVBClass)(pField + fSkip))->attr;
|
||
|
if (!getBaseDefnFromDecl(((plfVBClass)(pField + fSkip))->index, pName->pv, &newindex))
|
||
|
return SCN_error;
|
||
|
vbptr = ((plfVBClass)(pField + fSkip))->vbptr;
|
||
|
fSkip += offsetof (lfVBClass, vbpoff);
|
||
|
vbpoff = (UOFFSET)RNumLeaf (pField + fSkip, &fSkip);
|
||
|
offset = (UOFFSET)RNumLeaf (pField + fSkip, &fSkip);
|
||
|
if (pName->typeOut == newindex) {
|
||
|
// base has been found, set result values
|
||
|
|
||
|
MHOmfUnLock (hField);
|
||
|
if (IncrSymBase () != SCN_found) {
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
|
||
|
// save offset of base from address point for this
|
||
|
// pointer adjustment
|
||
|
|
||
|
if (SetBase (pName, newindex, vbptr, vbpoff, offset, attr, TRUE) != SCN_found) {
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pSymClass->viable = TRUE;
|
||
|
pName->possibles++;
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
termflag = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
if (termflag == TRUE) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
MHOmfUnLock (hField);
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*** SearchAERule - Search for auto-expansion rule
|
||
|
|
||
|
* flag = SearchAERule (pName)
|
||
|
|
||
|
* Description:
|
||
|
* The objective is to find an appropriate
|
||
|
* auto-expansion rule for a class that has no
|
||
|
* expansion rule associated with it. The idea
|
||
|
* is to use the expansion rule of a base class
|
||
|
* if one exists.
|
||
|
* The expansion rule is treated as a feature and
|
||
|
* the usual conventions apply regarding dominance
|
||
|
* and ambiguity.
|
||
|
|
||
|
* Entry pName = pointer to struct describing search
|
||
|
|
||
|
* Exit pName updated to reflect search
|
||
|
|
||
|
* Return enum describing search
|
||
|
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
SearchAERule (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
peval_t pvBase = &pSymClass->symbase[pSymClass->CurIndex].Base;
|
||
|
CV_typ_t type;
|
||
|
peval_t pvF = &pSymClass->evalP;
|
||
|
LSZ lsz;
|
||
|
SCN_t retval = SCN_notfound;
|
||
|
static char buf[256];
|
||
|
|
||
|
type = EVAL_TYP (pvBase);
|
||
|
lsz = GetTypeName (type, EVAL_MOD (pvBase));
|
||
|
if (LoadAERule (lsz, buf, sizeof (buf))) {
|
||
|
EVAL_MOD (pvF) = SHHMODFrompCXT (&pName->CXTT);
|
||
|
pvF->CXTT = pName->CXTT;
|
||
|
SetNodeType (pvF, type);
|
||
|
EVAL_STATE (pvF) = EV_type;
|
||
|
pSymClass->possibles = 1;
|
||
|
pName->possibles++;
|
||
|
pSymClass->viable = TRUE;
|
||
|
retval = SCN_found;
|
||
|
}
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*** SearchRoot - Search for an element of a class
|
||
|
|
||
|
* flag = SearchRoot (pName)
|
||
|
|
||
|
* Entry pName = pointer to struct describing search
|
||
|
* pvBase = pointer to value describing base to be searched
|
||
|
|
||
|
* Exit pName updated to reflect search
|
||
|
|
||
|
* Return enum describing search
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
SearchRoot (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
ulong cnt; // count of number of elements in struct
|
||
|
HTYPE hField; // handle to type record for struct field list
|
||
|
char *pField; // pointer to field list
|
||
|
HTYPE hBase; // handle to type record for base class
|
||
|
uint fSkip = 0; // offset in the field list
|
||
|
uint anchor; // offset in the field list to start of type
|
||
|
uint tSkip; // temporary offset in the field list
|
||
|
bool_t cmpflag = 1;
|
||
|
CV_typ_t newindex;
|
||
|
CV_typ_t vbptr;
|
||
|
SCN_t retval = SCN_notfound;
|
||
|
char *pc;
|
||
|
UQUAD value;
|
||
|
UOFFSET offset;
|
||
|
UOFFSET vbpoff;
|
||
|
CV_fldattr_t access;
|
||
|
int count;
|
||
|
CV_typ_t vfpType = T_NOTYPE;
|
||
|
peval_t pvBase = &pSymClass->symbase[pSymClass->CurIndex].Base;
|
||
|
CV_typ_t type;
|
||
|
peval_t pvF = &pSymClass->evalP;
|
||
|
UOFFSET vtabind;
|
||
|
ulong vbind;
|
||
|
|
||
|
// set hField to the handle of the field list for the class
|
||
|
|
||
|
if ((hField = THGetTypeFromIndex (EVAL_MOD (pvBase),
|
||
|
CLASS_FIELD (pvBase))) == 0) {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
|
||
|
// walk field list for the class
|
||
|
|
||
|
for (cnt = CLASS_COUNT (pvBase); cnt > 0; cnt--) {
|
||
|
fSkip += SkipPad(((uchar *)pField) + fSkip);
|
||
|
anchor = fSkip;
|
||
|
switch (((plfEasy)(pField + fSkip))->leaf) {
|
||
|
case LF_INDEX:
|
||
|
// switch to new type record because compiler split it up
|
||
|
newindex = ((plfIndex)(pField + fSkip))->index;
|
||
|
MHOmfUnLock (hField);
|
||
|
if ((hField = THGetTypeFromIndex (EVAL_MOD (pvBase), newindex)) == 0) {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
fSkip = 0;
|
||
|
// the LF_INDEX is not part of the field count
|
||
|
cnt++;
|
||
|
break;
|
||
|
|
||
|
case LF_MEMBER:
|
||
|
fSkip += offsetof (lfMember, offset);
|
||
|
offset = (UOFFSET)RNumLeaf (pField + fSkip, &fSkip);
|
||
|
access = ((plfMember)(pField + anchor))->attr;
|
||
|
pc = pField + fSkip;
|
||
|
fSkip += (*(pField + fSkip) + sizeof (char));
|
||
|
if (pName->clsmask & CLS_member) {
|
||
|
if ((cmpflag = fnCmp (pName, NULL, pc,
|
||
|
pExState->state.fCase)) == 0) {
|
||
|
type = ((plfMember)(pField + anchor))->index;
|
||
|
MHOmfUnLock (hField);
|
||
|
hField = 0;
|
||
|
EVAL_MOD (pvF) = SHHMODFrompCXT (&pName->CXTT);
|
||
|
SetNodeType (pvF, type);
|
||
|
EVAL_STATE (pvF) = EV_lvalue;
|
||
|
|
||
|
// save the casting data for the this pointer
|
||
|
|
||
|
pSymClass->offset = offset;
|
||
|
pSymClass->access = access;
|
||
|
pSymClass->possibles = 1;
|
||
|
pName->possibles++;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LF_ENUMERATE:
|
||
|
access = ((plfEnumerate)(pField + fSkip))->attr;
|
||
|
fSkip += offsetof (lfEnumerate, value);
|
||
|
value = RNumLeaf (pField + fSkip, &fSkip);
|
||
|
pc = pField + fSkip;
|
||
|
fSkip += *(pField + fSkip) + sizeof (char);
|
||
|
if (pName->clsmask & CLS_enumerate) {
|
||
|
if ((cmpflag = fnCmp (pName, NULL, pc,
|
||
|
pExState->state.fCase)) == 0) {
|
||
|
pSymClass->possibles = 1;
|
||
|
pName->possibles++;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LF_STMEMBER:
|
||
|
type = ((plfSTMember)(pField + anchor))->index;
|
||
|
fSkip += offsetof (lfSTMember, Name);
|
||
|
if (pName->clsmask & CLS_member) {
|
||
|
if ((cmpflag = fnCmp (pName, NULL, pField + fSkip,
|
||
|
pExState->state.fCase)) == 0) {
|
||
|
pSymClass->access =
|
||
|
((plfSTMember)(pField + anchor))->attr;
|
||
|
MHOmfUnLock (hField);
|
||
|
hField = 0;
|
||
|
EVAL_MOD (pvF) = SHHMODFrompCXT (&pName->CXTT);
|
||
|
SetNodeType (pvF, type);
|
||
|
EVAL_STATE (pvF) = EV_lvalue;
|
||
|
EVAL_IS_STMEMBER (pvF) = TRUE;
|
||
|
pSymClass->possibles = 1;
|
||
|
pName->possibles++;
|
||
|
}
|
||
|
}
|
||
|
fSkip += *(pField + fSkip) + sizeof (char);
|
||
|
break;
|
||
|
|
||
|
case LF_BCLASS:
|
||
|
type = ((plfBClass)(pField + anchor))->index;
|
||
|
access = ((plfBClass)(pField + anchor))->attr;
|
||
|
fSkip += offsetof (lfBClass, offset);
|
||
|
newindex = ((plfBClass)(pField + anchor))->index;
|
||
|
offset = (UOFFSET)RNumLeaf (pField + fSkip, &fSkip);
|
||
|
if ((pName->clsmask & CLS_bclass) != 0) {
|
||
|
|
||
|
// switch to the base class type record to check the name
|
||
|
|
||
|
MHOmfUnLock (hField);
|
||
|
if ((hBase = THGetTypeFromIndex (EVAL_MOD (pvBase), newindex)) == 0) {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hBase))->leaf);
|
||
|
tSkip = offsetof (lfClass, data);
|
||
|
RNumLeaf (pField + tSkip, &tSkip);
|
||
|
pc = pField + tSkip;
|
||
|
cmpflag = fnCmp (pName, NULL, pc, pExState->state.fCase);
|
||
|
MHOmfUnLock (hBase);
|
||
|
|
||
|
// reset to original field list
|
||
|
|
||
|
if (cmpflag == 0) {
|
||
|
|
||
|
// element has been found, set result values
|
||
|
|
||
|
pSymClass->isbase = TRUE;
|
||
|
pSymClass->isvbase = FALSE;
|
||
|
pSymClass->offset += offset;
|
||
|
EVAL_MOD (pvF) = SHHMODFrompCXT (&pName->CXTT);
|
||
|
SetNodeType (pvF, type);
|
||
|
EVAL_STATE (pvF) = EV_type;
|
||
|
pSymClass->access = access;
|
||
|
pSymClass->possibles = 1;
|
||
|
pName->possibles++;
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LF_VBCLASS:
|
||
|
type = ((plfBClass)(pField + anchor))->index;
|
||
|
access = ((plfVBClass)(pField + anchor))->attr;
|
||
|
newindex = ((plfVBClass)(pField + anchor))->index;
|
||
|
vbptr = ((plfVBClass)(pField + anchor))->vbptr;
|
||
|
fSkip += offsetof (lfVBClass, vbpoff);
|
||
|
vbpoff = (UOFFSET)RNumLeaf (pField + fSkip, &fSkip);
|
||
|
vbind = (ulong)RNumLeaf (pField + fSkip, &fSkip);
|
||
|
if ((pName->clsmask & CLS_bclass) != 0) {
|
||
|
|
||
|
// switch to the base class type record to check the name
|
||
|
|
||
|
MHOmfUnLock (hField);
|
||
|
if ((hBase = THGetTypeFromIndex (EVAL_MOD (pvBase), newindex)) == 0) {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hBase))->leaf);
|
||
|
tSkip = offsetof (lfClass, data);
|
||
|
RNumLeaf (pField + tSkip, &tSkip);
|
||
|
pc = pField + tSkip;
|
||
|
cmpflag = fnCmp (pName, NULL, pc, pExState->state.fCase);
|
||
|
MHOmfUnLock (hBase);
|
||
|
|
||
|
// reset to original field list
|
||
|
|
||
|
if (cmpflag == 0) {
|
||
|
|
||
|
// element has been found, set result values
|
||
|
|
||
|
pSymClass->isbase = FALSE;
|
||
|
pSymClass->isvbase = TRUE;
|
||
|
pSymClass->vbind = vbind;
|
||
|
pSymClass->vbpoff = vbpoff;
|
||
|
pSymClass->vbptr = vbptr;
|
||
|
EVAL_MOD (pvF) = SHHMODFrompCXT (&pName->CXTT);
|
||
|
SetNodeType (pvF, type);
|
||
|
EVAL_STATE (pvF) = EV_type;
|
||
|
pSymClass->access = access;
|
||
|
pSymClass->possibles = 1;
|
||
|
pName->possibles++;
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LF_IVBCLASS:
|
||
|
fSkip += offsetof (lfVBClass, vbpoff);
|
||
|
RNumLeaf (pField + fSkip, &fSkip);
|
||
|
RNumLeaf (pField + fSkip, &fSkip);
|
||
|
break;
|
||
|
|
||
|
case LF_FRIENDCLS:
|
||
|
newindex = ((plfFriendCls)(pField + fSkip))->index;
|
||
|
fSkip += sizeof (struct lfFriendCls);
|
||
|
if ((pName->clsmask & CLS_fclass) != 0) {
|
||
|
|
||
|
DASSERT (FALSE);
|
||
|
|
||
|
// switch to the base class type record to check the name
|
||
|
|
||
|
MHOmfUnLock (hField);
|
||
|
if ((hBase = THGetTypeFromIndex (EVAL_MOD (pvBase), newindex)) == 0) {
|
||
|
pExState->err_num = ERR_INTERNAL;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hBase))->data);
|
||
|
tSkip = offsetof (lfClass, data);
|
||
|
RNumLeaf (pField + tSkip, &tSkip);
|
||
|
pc = pField + tSkip;
|
||
|
cmpflag = fnCmp (pName, NULL, pc, pExState->state.fCase);
|
||
|
MHOmfUnLock (hBase);
|
||
|
|
||
|
// reset to original field list
|
||
|
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
if (cmpflag == 0) {
|
||
|
|
||
|
// element has been found, set result values
|
||
|
|
||
|
pName->typeOut = newindex;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LF_FRIENDFCN:
|
||
|
newindex = ((plfFriendFcn)(pField + fSkip))->index;
|
||
|
fSkip += sizeof (struct lfFriendFcn) +
|
||
|
((plfFriendFcn)(pField + fSkip))->Name[0];
|
||
|
if ((pName->clsmask & CLS_frmethod) != 0) {
|
||
|
DASSERT (FALSE);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LF_VFUNCTAB:
|
||
|
fSkip += sizeof (struct lfVFuncTab);
|
||
|
// save the type of the virtual function pointer
|
||
|
vfpType = ((plfVFuncTab)(pField + anchor))->type;
|
||
|
pc = vfuncptr;
|
||
|
if (pName->clsmask & CLS_vfunc) {
|
||
|
if ((cmpflag = fnCmp (pName, NULL, pc,
|
||
|
pExState->state.fCase)) == 0) {
|
||
|
MHOmfUnLock (hField);
|
||
|
hField = 0;
|
||
|
EVAL_MOD (pvF) = SHHMODFrompCXT (&pName->CXTT);
|
||
|
SetNodeType (pvF, vfpType);
|
||
|
EVAL_STATE (pvF) = EV_lvalue;
|
||
|
|
||
|
// save the casting data for the this pointer
|
||
|
|
||
|
if (pName->bnOp != 0) {
|
||
|
pSymClass->offset = 0;
|
||
|
pSymClass->access.access = CV_public;
|
||
|
}
|
||
|
pSymClass->possibles = 1;
|
||
|
pName->possibles++;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LF_ONEMETHOD:
|
||
|
count = 1;
|
||
|
newindex = ((plfOneMethod)(pField + fSkip))->index;
|
||
|
pc = pbNameInLfOneMethod((plfOneMethod)(pField + fSkip));
|
||
|
fSkip += uSkipLfOneMethod((plfOneMethod)(pField + fSkip));
|
||
|
if (pName->clsmask & CLS_method) {
|
||
|
if ((cmpflag = fnCmp (pName, NULL, pc, pExState->state.fCase)) == 0) {
|
||
|
// note that the OMF specifies that the vfuncptr will
|
||
|
// be emitted as the first field after the bases
|
||
|
|
||
|
if (pName->clsmask & CLS_virtintro) {
|
||
|
// we are looking for the introducing virtual
|
||
|
// method. We need to find a method with the
|
||
|
// correct name of the correct type index that
|
||
|
// is introducing.
|
||
|
|
||
|
MHOmfUnLock (hField);
|
||
|
if (IsIntroVirt (newindex) == FALSE) {
|
||
|
cmpflag = 1;
|
||
|
pField =
|
||
|
(char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
}
|
||
|
else {
|
||
|
pField =
|
||
|
(char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
if (FCN_VFPTYPE (pvF) == T_NOTYPE) {
|
||
|
FCN_VFPTYPE (pvF) = vfpType;
|
||
|
FCN_VFPTYPE (pName->pv) = vfpType;
|
||
|
FCN_VTABIND (pvF) = vtabind;
|
||
|
FCN_VTABIND (pName->pv) =
|
||
|
*((plfOneMethod)(pField + anchor))->vbaseoff;
|
||
|
}
|
||
|
cmpflag = 0;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
type = ((plfOneMethod)(pField + anchor))->index;
|
||
|
access = ((plfOneMethod)(pField + anchor))->attr;
|
||
|
FCN_VTABIND (pvF) = fIntroducingVirtual(access.mprop) ?
|
||
|
*((plfOneMethod)(pField + anchor))->vbaseoff : 0;
|
||
|
MHOmfUnLock (hField);
|
||
|
hField = 0;
|
||
|
EVAL_MOD (pvF) = SHHMODFrompCXT (&pName->CXTT);
|
||
|
SetNodeType (pvF, type);
|
||
|
EVAL_STATE (pvF) = EV_lvalue;
|
||
|
pSymClass->possibles = 1;
|
||
|
pName->possibles = 1;
|
||
|
pSymClass->mlist = type;
|
||
|
pSymClass->access = access;
|
||
|
pSymClass->vfpType = vfpType;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LF_METHOD:
|
||
|
count = ((plfMethod)(pField + fSkip))->count;
|
||
|
cnt -= count - 1;
|
||
|
newindex = ((plfMethod)(pField + fSkip))->mList;
|
||
|
pc = pField + anchor + offsetof (lfMethod, Name);
|
||
|
fSkip += sizeof (struct lfMethod) + *pc;
|
||
|
if (pName->clsmask & CLS_method) {
|
||
|
if ((cmpflag = fnCmp (pName, NULL, pc,
|
||
|
pExState->state.fCase)) == 0) {
|
||
|
// note that the OMF specifies that the vfuncptr will
|
||
|
// be emitted as the first field after the bases
|
||
|
|
||
|
if (pName->clsmask & CLS_virtintro) {
|
||
|
// we are looking for the introducing virtual
|
||
|
// method. We need to find a method with the
|
||
|
// correct name of the correct type index that
|
||
|
// is introducing.
|
||
|
|
||
|
MHOmfUnLock (hField);
|
||
|
if (IsIntroVirtInMlist (count, newindex, &vtabind) == FALSE) {
|
||
|
cmpflag = 1;
|
||
|
}
|
||
|
else {
|
||
|
if (FCN_VFPTYPE (pvF) == T_NOTYPE) {
|
||
|
FCN_VFPTYPE (pvF) = vfpType;
|
||
|
FCN_VFPTYPE (pName->pv) = vfpType;
|
||
|
FCN_VTABIND (pvF) = vtabind;
|
||
|
FCN_VTABIND (pName->pv) = vtabind;
|
||
|
}
|
||
|
cmpflag = 0;
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
}
|
||
|
else {
|
||
|
// save the type index of the method list, the
|
||
|
// count of methods overloaded on this name,
|
||
|
// the type index of the vfuncptr. Also,
|
||
|
// increment the number of possible features by
|
||
|
// the overload count
|
||
|
|
||
|
pSymClass->possibles = count;
|
||
|
pName->possibles += count;
|
||
|
pSymClass->mlist = newindex;
|
||
|
pSymClass->vfpType = vfpType;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case LF_NESTTYPE:
|
||
|
newindex = ((plfNestType)(pField + fSkip))->index;
|
||
|
fSkip += offsetof (lfNestType, Name);
|
||
|
pc = pField + fSkip;
|
||
|
fSkip += *(pField + fSkip) + sizeof (char);
|
||
|
if (pName->clsmask & CLS_ntype) {
|
||
|
if ((cmpflag = fnCmp (pName, NULL, pc,
|
||
|
pExState->state.fCase)) == 0) {
|
||
|
// set type of typedef symbol
|
||
|
pSymClass->possibles = 1;
|
||
|
pName->possibles++;
|
||
|
EVAL_STATE (pvF) = EV_type;
|
||
|
EVAL_TYP(pvF) = newindex;
|
||
|
}
|
||
|
else if (pName->clsmask & CLS_enumerate) {
|
||
|
// check if the nested type is an enum. if it is
|
||
|
// we gotta search thru its field list for a matching
|
||
|
// enumerate
|
||
|
// sps - 9/14/92
|
||
|
HTYPE hEnum, hEnumField; // nested handle
|
||
|
plfEnum pEnum;
|
||
|
char *pEnumField; // field list of the enum record
|
||
|
ulong enumCount;
|
||
|
uint fSkip = 0; // offset in the field list
|
||
|
uint anchor; // offset in the field list to start of type
|
||
|
|
||
|
if (CV_IS_PRIMITIVE(newindex)) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ((hEnum = THGetTypeFromIndex (EVAL_MOD (pvBase),
|
||
|
newindex)) == 0) {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pEnum = (plfEnum) (&((TYPPTR)MHOmfLock (hEnum))->leaf);
|
||
|
if (pEnum->leaf == LF_ENUM) {
|
||
|
if (pEnum->property.fwdref) {
|
||
|
eval_t localeval = *pvBase;
|
||
|
neval_t nv = &localeval;
|
||
|
|
||
|
// forward ref - look for the definition of the UDT
|
||
|
if ((newindex = GetUdtDefnTindex (newindex, pvBase, (char *)&(pEnum->Name[0]))) != T_NOTYPE) {
|
||
|
if ((hEnum = THGetTypeFromIndex (EVAL_MOD (pvBase), newindex)) == 0) {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pEnum = (plfEnum) (&((TYPPTR)MHOmfLock (hEnum))->leaf);
|
||
|
}
|
||
|
else
|
||
|
break; // No Fwd ref found... no CVInfo for nested type... proceed with search [rm]
|
||
|
}
|
||
|
if ((hEnumField = THGetTypeFromIndex (EVAL_MOD (pvBase),
|
||
|
pEnum->field)) == 0) {
|
||
|
if ( BindingBP ) {
|
||
|
break;
|
||
|
}
|
||
|
else {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
}
|
||
|
pEnumField = (char *)(&((TYPPTR)MHOmfLock (hEnumField))->data);
|
||
|
for (enumCount = pEnum->count; enumCount > 0; enumCount--) {
|
||
|
fSkip += SkipPad(((uchar *)pEnumField) + fSkip);
|
||
|
anchor = fSkip;
|
||
|
DASSERT ((((plfEasy)(pEnumField + fSkip))->leaf) == LF_ENUMERATE);
|
||
|
|
||
|
access = ((plfEnumerate)(pEnumField + fSkip))->attr;
|
||
|
fSkip += offsetof (lfEnumerate, value);
|
||
|
value = RNumLeaf (pEnumField + fSkip, &fSkip);
|
||
|
pc = pEnumField + fSkip;
|
||
|
fSkip += *(pEnumField + fSkip) + sizeof (char);
|
||
|
if ((cmpflag = fnCmp (pName, NULL, pc,
|
||
|
pExState->state.fCase)) == 0) {
|
||
|
EVAL_MOD (pvF) = SHHMODFrompCXT (&pName->CXTT);
|
||
|
SetNodeType (pvF, pEnum->utype);
|
||
|
EVAL_STATE (pvF) = EV_constant;
|
||
|
EVAL_QUAD (pvF) = value;
|
||
|
|
||
|
// save the casting data for the this pointer
|
||
|
|
||
|
pSymClass->access = access;
|
||
|
pSymClass->possibles = 1;
|
||
|
pName->possibles++;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
MHOmfUnLock (hEnumField);
|
||
|
}
|
||
|
MHOmfUnLock (hEnum);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
retval = SCN_notfound;
|
||
|
|
||
|
}
|
||
|
#ifdef NEVER
|
||
|
// if ((cnt == 0) && ** (pName->tTypeDef != 0)) {
|
||
|
if ((cnt == 0) && (pName->tTypeDef != 0)) {
|
||
|
// we found a typedef name that was not hidden by
|
||
|
// a member or method name
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (cmpflag == 0) {
|
||
|
pSymClass->viable = TRUE;
|
||
|
retval = SCN_found;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (hField != 0) {
|
||
|
MHOmfUnLock (hField);
|
||
|
}
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** SetBPValue - set the breakpoint list from a class search
|
||
|
|
||
|
* status = SetBPValue (pName)
|
||
|
|
||
|
* Entry pName = pointer to structure describing search
|
||
|
* pSymCl = pointer to class element
|
||
|
|
||
|
* Exit pName updated to reflect found feature
|
||
|
* this pointer inserted in bind tree if feature is part of
|
||
|
* the class pointed to by this pointer of method
|
||
|
|
||
|
* Returns SCN_rewrite if this pointer inserted (rebind required)
|
||
|
* SCN_found if no error
|
||
|
* SCN_error otherwise
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
SetBPValue (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
peval_t pv;
|
||
|
|
||
|
DASSERT ((pName->cFound == 0) && (pName->hFound == 0));
|
||
|
if (pSymClass->mlist != T_NOTYPE) {
|
||
|
if ((pName->possibles == 1) || (bArgList != 0)) {
|
||
|
switch (MatchMethod (pName, pSymClass)) {
|
||
|
default:
|
||
|
DASSERT (FALSE);
|
||
|
case MTH_error:
|
||
|
return (SCN_error);
|
||
|
|
||
|
case MTH_found:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
// we have a list of functions and no argument list.
|
||
|
// This means that we have an ambiguous breakpoint
|
||
|
// and need to add the functions to the breakpoint
|
||
|
// list for user disambiguation. Basically what
|
||
|
// we are going to do is force all of the methods
|
||
|
// into the breakpoint list and let later
|
||
|
// binding resolve any errors.
|
||
|
|
||
|
return (OverloadToAmbList (pName, pSymClass));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// at this point, the following values are set
|
||
|
// pName->addr = address of method if not virtual method
|
||
|
// pName->typeOut = type index of method
|
||
|
// pName->hSym = handle of symbol for function
|
||
|
|
||
|
pv = &pSymClass->evalP;
|
||
|
if (fAnyVirtual(FCN_ATTR (pv).mprop)) {
|
||
|
pExState->err_num = ERR_NOVIRTUALBP;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pv = pName->pv;
|
||
|
*pv = pSymClass->evalP;
|
||
|
EVAL_ACCESS (pv) = (uchar)(pSymClass->access.access);
|
||
|
pName->typeOut = EVAL_TYP (pv);
|
||
|
|
||
|
// save the offset of a class member
|
||
|
// (caviar #1756) --gdp 9-10-92
|
||
|
|
||
|
if (pName->bnOp) {
|
||
|
peval_t pvOp = &pName->bnOp->v[0];
|
||
|
EVAL_IS_MEMBER(pvOp) = TRUE;
|
||
|
MEMBER_OFFSET(pvOp) = pName->initializer == INIT_right ?
|
||
|
pSymClass->offset : 0;
|
||
|
}
|
||
|
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
OverloadToAmbList (
|
||
|
psearch_t pName,
|
||
|
psymclass_t pSymCl
|
||
|
)
|
||
|
{
|
||
|
SCN_t retval;
|
||
|
|
||
|
// add the first list of methods
|
||
|
|
||
|
if ((retval = MethodsToAmbList (pName, pSymCl)) != SCN_found) {
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
// loop through the remaining class descriptors adding them to the list
|
||
|
|
||
|
while (pName->hAmbCl != 0) {
|
||
|
MoveSymCl (pName->hAmbCl);
|
||
|
if ((retval = MethodsToAmbList (pName,pSymCl)) != SCN_found) {
|
||
|
return (retval);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pExState->ambiguous == 0) {
|
||
|
// no instantiated function has been found
|
||
|
return (SCN_notfound);
|
||
|
}
|
||
|
|
||
|
SymToNode (pName);
|
||
|
DASSERT (EVAL_TYP (pName->pv) != T_NOTYPE);
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** MethodsToAmbList - add a list of methods to ambiguous breakpoints
|
||
|
|
||
|
* flag = MethodsToAmbList (pName, pSymCl)
|
||
|
|
||
|
* Entry pName = pointer to search descriptor
|
||
|
* pSymCl = pointer to symbol class structure
|
||
|
|
||
|
* Exit methods added to list of ambiguous breakpoints
|
||
|
|
||
|
* Returns SCN_found if methods added
|
||
|
* SCN_error if error during addition
|
||
|
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
MethodsToAmbList (
|
||
|
psearch_t pName,
|
||
|
psymclass_t pSymCl
|
||
|
)
|
||
|
{
|
||
|
HTYPE hMethod;
|
||
|
pmlMethod pMethod;
|
||
|
uint skip;
|
||
|
CV_fldattr_t attr;
|
||
|
CV_typ_t type;
|
||
|
UOFFSET vtabind;
|
||
|
HDEP hQual;
|
||
|
peval_t pvF;
|
||
|
ulong count = pSymCl->possibles;
|
||
|
peval_t pvB;
|
||
|
HMOD hMod;
|
||
|
HDEP hTemp;
|
||
|
psearch_t pTemp;
|
||
|
bool_t retval;
|
||
|
|
||
|
pvB = &pSymCl->symbase[pSymCl->CurIndex].Base;
|
||
|
hMod = EVAL_MOD (pvB);
|
||
|
|
||
|
// we now walk the list of methods adding each method to the list of
|
||
|
// ambiguous breakpoints
|
||
|
|
||
|
if ((hMethod = THGetTypeFromIndex (hMod, pSymCl->mlist)) == NULL) {
|
||
|
DASSERT (FALSE);
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
|
||
|
// set the number of methods overloaded on this name and the index into
|
||
|
// the method list
|
||
|
|
||
|
skip = 0;
|
||
|
while (count-- > 0) {
|
||
|
// lock the omf record, extract information for the current entry in
|
||
|
// the method list and increment to field for next method
|
||
|
|
||
|
pMethod = (pmlMethod)((&((TYPPTR)MHOmfLock (hMethod))->leaf) + 1);
|
||
|
pMethod = (pmlMethod)((uchar *)pMethod + skip);
|
||
|
attr = pMethod->attr;
|
||
|
type = pMethod->index;
|
||
|
skip += sizeof (mlMethod);
|
||
|
if (fIntroducingVirtual(pMethod->attr.mprop)) {
|
||
|
vtabind = pMethod->vbaseoff[0];
|
||
|
skip += sizeof(pMethod->vbaseoff[0]);
|
||
|
}
|
||
|
else {
|
||
|
vtabind = 0;
|
||
|
}
|
||
|
MHOmfUnLock (hMethod);
|
||
|
|
||
|
// now add the method to the list
|
||
|
|
||
|
pvF = &pSymCl->evalP;
|
||
|
EVAL_MOD (pvF) = hMod;
|
||
|
DASSERT (type != T_NOTYPE);
|
||
|
if (SetNodeType (pvF, type) == FALSE) {
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
else {
|
||
|
FCN_ATTR (pvF) = attr;
|
||
|
FCN_VTABIND (pvF) = vtabind;
|
||
|
FCN_VFPTYPE (pvF) = pSymCl->vfpType;
|
||
|
pName->best.match = type;
|
||
|
|
||
|
// If we have an expression such as pFoo->vFunc we
|
||
|
// should not be setting a bp on CFoo::vFunc where
|
||
|
// CFoo is the static type to which pFoo points.
|
||
|
// We have to exclude the case where we are explicitly
|
||
|
// setting a bp on CFoo::vfunc of course.
|
||
|
|
||
|
if (BindingBP && (NODE_OP(pName->bnOp) != OP_bscope)
|
||
|
&& fAnyVirtual(FCN_ATTR(pvF).mprop))
|
||
|
{
|
||
|
pExState->err_num = ERR_NOVIRTUALBP;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
|
||
|
if (((hQual = GenQualName (pName, pSymCl)) == 0) ||
|
||
|
(SearchQualName (pName, pSymCl, hQual, TRUE) == FALSE)) {
|
||
|
if (hQual != 0) {
|
||
|
MemFree (hQual);
|
||
|
}
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
MemFree (hQual);
|
||
|
}
|
||
|
if (FCN_NOTPRESENT (pvF) == FALSE) {
|
||
|
if (pExState->ambiguous == 0) {
|
||
|
// we have found the first function. We need to set all of
|
||
|
// the return values in the pointer to the search entry
|
||
|
|
||
|
pExState->ambiguous = pName->bn;
|
||
|
|
||
|
// at this point, the following values are set
|
||
|
// pName->addr = address of method if not virtual method
|
||
|
// pName->typeOut = type index of method
|
||
|
// pName->hSym = handle of symbol for function
|
||
|
|
||
|
*pName->pv = pSymClass->evalP;
|
||
|
EVAL_ACCESS (pName->pv) = (uchar)(pSymClass->access.access);
|
||
|
pName->typeOut = EVAL_TYP (pName->pv);
|
||
|
pName->hSym = EVAL_HSYM (pvF);
|
||
|
}
|
||
|
else {
|
||
|
if ((hTemp = MemAllocate (sizeof (search_t))) == 0) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pTemp = (psearch_t) MemLock (hTemp);
|
||
|
*pTemp = *pName;
|
||
|
pTemp->hSym = pvF->hSym;
|
||
|
retval = AmbToList (pTemp);
|
||
|
MemUnLock (hTemp);
|
||
|
MemFree (hTemp);
|
||
|
if (retval == FALSE) {
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
|
||
|
|
||
|
/** SetValue - set the result of the class search
|
||
|
|
||
|
* status = SetValue (pName)
|
||
|
|
||
|
* Entry pName = pointer to structure describing search
|
||
|
* pSymClass = pointer to class element
|
||
|
|
||
|
* Exit pName updated to reflect found feature
|
||
|
* this pointer inserted in bind tree if feature is part of
|
||
|
* the class pointed to by this pointer of method
|
||
|
|
||
|
* Returns SCN_rewrite if this pointer inserted (rebind required)
|
||
|
* SCN_found if no error
|
||
|
* SCN_error otherwise
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
SetValue (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
peval_t pv;
|
||
|
peval_t pvOp;
|
||
|
SCN_t retval;
|
||
|
HDEP hQual;
|
||
|
|
||
|
// When we get here, the situation is a bit complex.
|
||
|
// If we are not binding breakpoints, the following conditions
|
||
|
// must be true:
|
||
|
// pName->hAmbCl = 0 (only one feature can remain after dominance)
|
||
|
// pName->cFound = 0
|
||
|
// pName->hFound = 0
|
||
|
// pSymClass->viable = TRUE
|
||
|
// If the feature is a data item (pSymClass->mlist == T_NOTYPE), then
|
||
|
// pName->possibles = 1
|
||
|
// If the feature is a method, then
|
||
|
// pName->possibles = number of overloads on name
|
||
|
// pSymClass->mlist = type index of member list
|
||
|
// bArgList = based pointer to argument list tree (cannot be 0)
|
||
|
// Argument matching must result in a best match to a single method
|
||
|
|
||
|
// If we are binding breakpoints, the following conditions must be true
|
||
|
// pName->cFound = 0
|
||
|
// pName->hFound = 0
|
||
|
// pName->possibles = total number of methods in pSymClass and
|
||
|
// pName->hAmbCl
|
||
|
// pName->hAmbCl > 0 if two or more features survived dominance
|
||
|
// Each of the features in pSymClass and the pName->hAmbCl list
|
||
|
// must be a method list (pSymClass->mlist != T_NOTYPE)
|
||
|
|
||
|
// If we do not have an argument list, then we accept all methods in
|
||
|
// pSymClass->mlist and pName->hAmbCl.mlist. The number of methods is
|
||
|
// pName->possibles.
|
||
|
|
||
|
// If we do have an argument list, then we accept all methods in
|
||
|
// pSymClass->mlist and pName->hAmbCl.mlist that are exact matches
|
||
|
// for the argument list. Implicit conversions are not considered.
|
||
|
// The number of methods must less than 1 + number of elements in the
|
||
|
// list pName->hAmbCl and must be less than or equal to pName->possibles.
|
||
|
|
||
|
if (BindingBP == TRUE) {
|
||
|
// call the set of routines that will process breakpoints on methods
|
||
|
// of a class, the inheritance tree of the class and the derivation
|
||
|
// tree of the class. If the routine returns without error, pName
|
||
|
// describes the first function breakpoint and hTMList describes the
|
||
|
// remainder of the list of methods that match the function and
|
||
|
// signature if one is specified.
|
||
|
|
||
|
return (SetBPValue (pName));
|
||
|
}
|
||
|
// At this point, there must be only one class after dominance resolution,
|
||
|
// the count of the found items must be zero, and the handle of the found
|
||
|
// item list must be null. Otherwise there was a failure in dominance
|
||
|
// resolution.
|
||
|
|
||
|
DASSERT ((pName->hAmbCl == 0) &&
|
||
|
(pName->cFound == 0) &&
|
||
|
(pName->hFound == 0) &&
|
||
|
(pSymClass->viable == TRUE));
|
||
|
if (pSymClass->mlist == T_NOTYPE) {
|
||
|
DASSERT (pName->possibles == 1);
|
||
|
}
|
||
|
else if ((pName->possibles > 1) && (bArgList == 0)) {
|
||
|
pExState->err_num = ERR_NOARGLIST;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
|
||
|
// if we are processing C++, then we can allow for overloaded methods
|
||
|
// which is specified by the type index of the method list not being
|
||
|
// zero. If this is true, then we select the best of the overloaded
|
||
|
// methods.
|
||
|
|
||
|
if (pSymClass->mlist != T_NOTYPE) {
|
||
|
switch (MatchMethod (pName, pSymClass)) {
|
||
|
default:
|
||
|
DASSERT (FALSE);
|
||
|
case MTH_error:
|
||
|
return (SCN_error);
|
||
|
|
||
|
case MTH_found:
|
||
|
// at this point, the following values are set
|
||
|
// pName->addr = address of method if not virtual method
|
||
|
// pName->typeOut = type index of method
|
||
|
// pName->hSym = handle of symbol for function
|
||
|
|
||
|
pv = &pSymClass->evalP;
|
||
|
if (fNonIntroVirtual(FCN_ATTR (pv).mprop)) {
|
||
|
// search to introducing virtual method
|
||
|
if ((retval = FindIntro (pName)) != SCN_found) {
|
||
|
return (retval);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pName->initializer == INIT_AErule) {
|
||
|
pv = pName->pv;
|
||
|
*pv = pSymClass->evalP;
|
||
|
pName->typeOut = EVAL_TYP (pv);
|
||
|
return SCN_found;
|
||
|
}
|
||
|
|
||
|
// the symbol is a data member of the class (C or C++). If an
|
||
|
// explict class was not specified and the current context is
|
||
|
// implicitly a class (we are in the scope of the method of the class),
|
||
|
// then we rewrite the tree to change the symbol reference to this->symbol
|
||
|
|
||
|
if ((pName->initializer != INIT_base) &&
|
||
|
(pName->initializer != INIT_sym) &&
|
||
|
(pName->ExpClass == 0)) {
|
||
|
//DASSERT (FALSE);
|
||
|
pExState->err_num = ERR_INTERNAL;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
|
||
|
else if ((pName->ExpClass == 0) && (ClassImp != 0) &&
|
||
|
(pName->initializer != INIT_base) && !EVAL_IS_STMEMBER(&pSymClass->evalP)) {
|
||
|
// CUDA #4030: handle access to static members from
|
||
|
// inside a static member function w/o referring to "this"
|
||
|
// don't run this code for static members because "this"
|
||
|
// might not be available [rm]
|
||
|
|
||
|
// if we are looking at a nested enumerate - don't need the
|
||
|
// rewrite
|
||
|
// sps 9/15/92
|
||
|
// or if we are looking at a base class or nested class type
|
||
|
// we don't need to rewrite
|
||
|
// rm 5/6/93
|
||
|
|
||
|
ulong state = EVAL_STATE(&(pSymClass->evalP));
|
||
|
|
||
|
if (state == EV_constant || state == EV_type) {
|
||
|
*pName->pv = pSymClass->evalP;
|
||
|
return(SCN_found);
|
||
|
}
|
||
|
|
||
|
// if the feature is a member of *this class of a method, then
|
||
|
// we need to rewrite
|
||
|
// feature
|
||
|
// to
|
||
|
// this->feature
|
||
|
// The calling routine will need to rebind the expression
|
||
|
|
||
|
InsertThis (pName);
|
||
|
return (SCN_rewrite);
|
||
|
}
|
||
|
|
||
|
// CUDA #4030: do minimal setup of *pv in the INIT_sym case so that we do
|
||
|
// the right search in the static member access case. Otherwise
|
||
|
// the initializer for the search must be INIT_right or INIT_base.
|
||
|
// by the time we get to here we know that bnOp is the based pointer to
|
||
|
// the node that will receive the casting expression and pv points
|
||
|
// to the feature node.
|
||
|
|
||
|
pv = pName->pv;
|
||
|
pvOp = &pName->bnOp->v[0];
|
||
|
switch (pName->initializer) {
|
||
|
case INIT_right:
|
||
|
*pv = pSymClass->evalP;
|
||
|
EVAL_ACCESS (pv) = (uchar)(pSymClass->access.access);
|
||
|
pName->typeOut = EVAL_TYP (pv);
|
||
|
EVAL_IS_MEMBER (pvOp) = TRUE;
|
||
|
MEMBER_TYPE (pvOp) = EVAL_TYP (pv);
|
||
|
MEMBER_OFFSET (pvOp) = pSymClass->offset;
|
||
|
MEMBER_ACCESS (pvOp) = pSymClass->access;
|
||
|
if ((pSymClass->isvbase == TRUE) || (pSymClass->isivbase == TRUE)) {
|
||
|
MEMBER_VBASE (pvOp) = pSymClass->isvbase;
|
||
|
MEMBER_IVBASE (pvOp) = pSymClass->isivbase;
|
||
|
MEMBER_VBPTR (pvOp) = pSymClass->vbptr;
|
||
|
MEMBER_VBPOFF (pvOp) = pSymClass->vbpoff;
|
||
|
MEMBER_VBIND (pvOp) = pSymClass->vbind;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case INIT_base:
|
||
|
*pv = pSymClass->symbase[pSymClass->CurIndex].Base;
|
||
|
EVAL_ACCESS (pv) = (uchar)(pSymClass->symbase[pSymClass->
|
||
|
CurIndex].attrBC.access);
|
||
|
pName->typeOut = EVAL_TYP (pv);
|
||
|
EVAL_IS_MEMBER (pvOp) = TRUE;
|
||
|
EVAL_ACCESS (pvOp) = (uchar)(pSymClass->symbase[pSymClass->
|
||
|
CurIndex].attrBC.access);
|
||
|
MEMBER_OFFSET (pvOp) = 0;
|
||
|
break;
|
||
|
|
||
|
case INIT_sym:
|
||
|
// CUDA #4030: handle access to static members from
|
||
|
// inside a static member function w/o referring to "this" [rm]
|
||
|
|
||
|
// symbol MUST BE a static member, just setup *pv...
|
||
|
|
||
|
DASSERT(EVAL_IS_STMEMBER(&pSymClass->evalP));
|
||
|
*pv = pSymClass->evalP;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
DASSERT (FALSE);
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
|
||
|
if (EVAL_IS_STMEMBER (pv) == FALSE) {
|
||
|
// the feature is not a static data member of the class
|
||
|
return (GenQualExpr (pName));
|
||
|
}
|
||
|
else {
|
||
|
// the feature is a static member so we need to generate the
|
||
|
// qualified path and search for a symbol of the correct type
|
||
|
// so we can set the address
|
||
|
|
||
|
if (((hQual = GenQualName (pName, pSymClass)) == 0) ||
|
||
|
(SearchQualName (pName, pSymClass, hQual, FALSE) == FALSE)) {
|
||
|
if (hQual != 0) {
|
||
|
MemFree (hQual);
|
||
|
}
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
*pv = pSymClass->evalP;
|
||
|
EVAL_STATE (pv) = EV_lvalue;
|
||
|
MemFree (hQual);
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// Support routines
|
||
|
|
||
|
/** AddETConst - add evalthisconst node
|
||
|
|
||
|
* pn = AddETConst (pnP, off, btype)
|
||
|
|
||
|
* Entry pnP = pointer to previous node
|
||
|
|
||
|
* Exit OP_evalthisconst node added to bind tree
|
||
|
* current node linked to pnP as left child if pnP != NULL
|
||
|
* pTree->node_next advanced
|
||
|
* btype = type of the base class
|
||
|
|
||
|
* Returns pointer to node just allocated
|
||
|
*/
|
||
|
|
||
|
|
||
|
pnode_t
|
||
|
AddETConst (
|
||
|
pnode_t pnP,
|
||
|
UOFFSET off,
|
||
|
CV_typ_t btype
|
||
|
)
|
||
|
{
|
||
|
pnode_t pn;
|
||
|
padjust_t pa;
|
||
|
|
||
|
pn = (pnode_t)(((char *)pTree) + pTree->node_next);
|
||
|
pa = (padjust_t)(&pn->v[0]);
|
||
|
memset (pn, 0, sizeof (node_t) + sizeof (adjust_t));
|
||
|
NODE_OP (pn) = OP_thisconst;
|
||
|
pa->btype = btype;
|
||
|
pa->disp = off;
|
||
|
if (pnP != NULL) {
|
||
|
NODE_LCHILD (pnP) = (bnode_t)pn;
|
||
|
}
|
||
|
pTree->node_next += sizeof (node_t) + sizeof (adjust_t);
|
||
|
return (pn);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** AddETInit - add evalthisinit node
|
||
|
|
||
|
* pn = AddETInit (pnP, btype)
|
||
|
|
||
|
* Entry pnP = pointer to previous node
|
||
|
|
||
|
* Exit OP_evalthisinit node added to bind tree
|
||
|
* current node linked to pnP as left child if pnP != NULL
|
||
|
* pTree->node_next advanced
|
||
|
* btype = type of the base class
|
||
|
|
||
|
* Returns pointer to node just allocated
|
||
|
*/
|
||
|
|
||
|
|
||
|
pnode_t
|
||
|
AddETInit (
|
||
|
pnode_t pnP,
|
||
|
CV_typ_t btype
|
||
|
)
|
||
|
{
|
||
|
pnode_t pn;
|
||
|
padjust_t pa;
|
||
|
|
||
|
pn = (pnode_t)(((char *)pTree) + pTree->node_next);
|
||
|
pa = (padjust_t)(&pn->v[0]);
|
||
|
memset (pn, 0, sizeof (node_t) + sizeof (adjust_t));
|
||
|
NODE_OP (pn) = OP_thisinit;
|
||
|
pa->btype = btype;
|
||
|
if (pnP != NULL) {
|
||
|
NODE_LCHILD (pnP) = (bnode_t)pn;
|
||
|
}
|
||
|
pTree->node_next += sizeof (node_t) + sizeof (adjust_t);
|
||
|
return (pn);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** AddETExpr - add evalthisexpr node
|
||
|
|
||
|
* pn = AddETExpr (pnP, vbptr, vbpoff, vbind, btype)
|
||
|
|
||
|
* Entry pnP = pointer to previous node
|
||
|
* vbptr = type index of virtual base pointer
|
||
|
* vboff = offset of vbptr from address point
|
||
|
* vbdisp = offset of displacement in virtual base table
|
||
|
* btype = type of the base class
|
||
|
|
||
|
* Exit OP_evalthisconst node added to bind tree
|
||
|
* current node linked to pnP as left child if pnP != NULL
|
||
|
* pTree->node_next advanced
|
||
|
|
||
|
* Returns pointer to node just allocated
|
||
|
|
||
|
* The evaluation of this node will result in
|
||
|
|
||
|
* ab = (ap * vbpoff) + *(*(ap +vbpoff) + vbdisp)
|
||
|
* where
|
||
|
* ab = address of base class
|
||
|
* ap = current address point
|
||
|
*/
|
||
|
|
||
|
|
||
|
pnode_t
|
||
|
AddETExpr (
|
||
|
pnode_t pnP,
|
||
|
CV_typ_t vbptr,
|
||
|
UOFFSET vbpoff,
|
||
|
UOFFSET vbdisp,
|
||
|
CV_typ_t btype
|
||
|
)
|
||
|
{
|
||
|
pnode_t pn;
|
||
|
padjust_t pa;
|
||
|
|
||
|
pn = (pnode_t)(((char *)pTree) + pTree->node_next);
|
||
|
pa = (padjust_t)(&pn->v[0]);
|
||
|
memset (pn, 0, sizeof (node_t) + sizeof (adjust_t));
|
||
|
NODE_OP (pn) = OP_thisexpr;
|
||
|
pa->btype = btype;
|
||
|
pa->disp = vbdisp;
|
||
|
pa->vbpoff = vbpoff;
|
||
|
pa->vbptr = vbptr;
|
||
|
if (pnP != NULL) {
|
||
|
NODE_LCHILD (pnP) = (bnode_t)pn;
|
||
|
}
|
||
|
pTree->node_next += sizeof (node_t) + sizeof (adjust_t);
|
||
|
return (pn);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** AddVBList - Add virtual bases to searched or dominated list
|
||
|
|
||
|
* status = AddVBList (pSymClass, ppList, phMem)
|
||
|
|
||
|
* Entry pSymClass = pointer to base class path list structure
|
||
|
* ppList = pointer to dominated or searched list
|
||
|
* phMem = pointer to handle for ppList
|
||
|
|
||
|
* Exit virtual bases added to list
|
||
|
|
||
|
* Return SCN_found if all bases added to list
|
||
|
* SCN_error if bases could not be added
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
AddVBList (
|
||
|
psymclass_t pSymClass,
|
||
|
pdombase_t *ppList,
|
||
|
HDEP * phList
|
||
|
)
|
||
|
{
|
||
|
ulong cnt; // count of number of elements in struct
|
||
|
HTYPE hField; // handle to type record for struct field list
|
||
|
char *pField; // pointer to field list
|
||
|
uint fSkip = 0; // offset in the field list
|
||
|
uint anchor; // offset in the field list to start of type
|
||
|
CV_typ_t newindex;
|
||
|
SCN_t retval = SCN_found;
|
||
|
bool_t termflag = FALSE;
|
||
|
peval_t pvBase = &pSymClass->symbase[pSymClass->CurIndex].Base;
|
||
|
|
||
|
// set hField to the handle of the field list for the class
|
||
|
|
||
|
if ((hField = THGetTypeFromIndex (EVAL_MOD (pvBase), CLASS_FIELD (pvBase))) == 0) {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
|
||
|
// walk field list for the class
|
||
|
|
||
|
for (cnt = CLASS_COUNT (pvBase); cnt > 0; cnt--) {
|
||
|
fSkip += SkipPad(((uchar *)pField) + fSkip);
|
||
|
anchor = fSkip;
|
||
|
switch (((plfEasy)(pField + fSkip))->leaf) {
|
||
|
case LF_INDEX:
|
||
|
// switch to new type record because compiler split it up
|
||
|
newindex = ((plfIndex)(pField + fSkip))->index;
|
||
|
MHOmfUnLock (hField);
|
||
|
if ((hField = THGetTypeFromIndex (EVAL_MOD (pvBase), newindex)) == 0) {
|
||
|
pExState->err_num = ERR_INTERNAL;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hField))->data);
|
||
|
fSkip = 0;
|
||
|
// the LF_INDEX is not part of the field count
|
||
|
cnt++;
|
||
|
break;
|
||
|
|
||
|
case LF_BCLASS:
|
||
|
// skip direct base class
|
||
|
fSkip += offsetof (lfBClass, offset);
|
||
|
RNumLeaf (pField + fSkip, &fSkip);
|
||
|
break;
|
||
|
|
||
|
case LF_VBCLASS:
|
||
|
case LF_IVBCLASS:
|
||
|
newindex = ((plfVBClass)(pField + fSkip))->index;
|
||
|
if ((retval = AddVBType (ppList, phList, newindex)) == SCN_error) {
|
||
|
termflag = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
fSkip += offsetof (lfVBClass, vbpoff);
|
||
|
RNumLeaf (pField + fSkip, &fSkip);
|
||
|
RNumLeaf (pField + fSkip, &fSkip);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
termflag = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
if (termflag == TRUE) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
MHOmfUnLock (hField);
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*** AddVBType - Add virtual base to list
|
||
|
|
||
|
* status = AddVBType (ppList, phList, type)
|
||
|
|
||
|
* Entry ppList = pointer to dominated or searched list
|
||
|
* phList = pointer to handle for ppList
|
||
|
* type = type index
|
||
|
|
||
|
* Exit type added to list
|
||
|
|
||
|
* Return SCN_found if all bases added to list
|
||
|
* SCN_error if bases could not be added
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
AddVBType (
|
||
|
pdombase_t *ppList,
|
||
|
HDEP *phList,
|
||
|
CV_typ_t type
|
||
|
)
|
||
|
{
|
||
|
ulong i;
|
||
|
bool_t add = TRUE;
|
||
|
ulong len;
|
||
|
pdombase_t pList = *ppList;
|
||
|
HDEP hList;
|
||
|
|
||
|
for (i = 0; i < pList->CurIndex; i++) {
|
||
|
if (type == pList->dom[i]) {
|
||
|
add = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (add == TRUE) {
|
||
|
if (pList->CurIndex >= pList->MaxIndex) {
|
||
|
len = sizeof (dombase_t) + (pList->MaxIndex + 10) * sizeof (CV_typ_t);
|
||
|
MemUnLock (*phList);
|
||
|
if ((hList = MemReAlloc (*phList, len)) == 0) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
pList = (pdombase_t) MemLock (*phList);
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
else {
|
||
|
*phList = hList;
|
||
|
*ppList = pList = (pdombase_t) MemLock (*phList);
|
||
|
pList->MaxIndex += 10;
|
||
|
}
|
||
|
}
|
||
|
pList->dom[pList->CurIndex++] = type;
|
||
|
}
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
|
||
|
|
||
|
/** AmbFromList - add get next ambiguous symbol from list
|
||
|
|
||
|
* status = AmbFromList (pName)
|
||
|
|
||
|
* Entry pName = pointer to list describing search
|
||
|
|
||
|
* Exit breakpoint added to list of breakpoints
|
||
|
* pName reset to continue breakpoint search
|
||
|
|
||
|
* Returns HR_found if breakpoint added
|
||
|
* HR_error if breakpoint could not be added to list
|
||
|
*/
|
||
|
|
||
|
ulong
|
||
|
AmbFromList (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
psearch_t pBPatch;
|
||
|
|
||
|
pBPatch = (psearch_t) MemLock (hBPatch);
|
||
|
*pName = *pBPatch;
|
||
|
MemUnLock (hBPatch);
|
||
|
pName->pv = &pName->bn->v[0];
|
||
|
EVAL_HSYM (pName->pv) = pName->hSym;
|
||
|
if ((SymToNode (pName) == TRUE) && (PushStack (pName->pv) == TRUE)) {
|
||
|
return (HR_found);
|
||
|
}
|
||
|
else {
|
||
|
return (HR_error);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** AmbToList - add ambiguous symbol to list
|
||
|
|
||
|
* fSuccess = AmbToList (pName)
|
||
|
|
||
|
* Entry pName = pointer to list describing search
|
||
|
|
||
|
* Exit ambiguous symbol added to list pointed to by pTMList
|
||
|
* pTMLbp
|
||
|
|
||
|
* Returns TRUE if symbol added
|
||
|
* FALSE if error
|
||
|
*/
|
||
|
|
||
|
bool_t
|
||
|
AmbToList (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
HDEP hBPatch;
|
||
|
psearch_t pBPatch;
|
||
|
|
||
|
if (iBPatch >= pTMLbp->cTMListMax) {
|
||
|
// the back patch list has filled the TM list
|
||
|
if (!GrowTMList ()) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (FALSE);
|
||
|
}
|
||
|
}
|
||
|
if ((hBPatch = MemAllocate (sizeof (search_t))) != 0) {
|
||
|
pTMList[iBPatch++] = hBPatch;
|
||
|
pBPatch = (psearch_t) MemLock (hBPatch);
|
||
|
*pBPatch = *pName;
|
||
|
// save address of function in order to check for
|
||
|
// duplicates
|
||
|
pBPatch->typeOut = EVAL_TYP(pName->pv);
|
||
|
pBPatch->addr = EVAL_SYM(pName->pv);
|
||
|
MemUnLock (hBPatch);
|
||
|
return (TRUE);
|
||
|
}
|
||
|
else {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (FALSE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** DupSymCl - duplicate symbol class structure and link to list
|
||
|
|
||
|
* DupSymCl (pName);
|
||
|
|
||
|
* Entry pName = handle of structure describing search
|
||
|
* *pSymClass = symbol class structure
|
||
|
|
||
|
* Exit *pSymClass = duplicated and linked to list pName->hFound
|
||
|
* pSymClass->viable = FALSE
|
||
|
|
||
|
* Returns SCN_found if pSymClass duplicated
|
||
|
* SCN_error if unable to allocate memory for duplication
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
DupSymCl (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
HDEP hSymCl;
|
||
|
psymclass_t pSymCl;
|
||
|
ulong size;
|
||
|
|
||
|
size = (ulong ) (sizeof (symclass_t) + (pSymClass->CurIndex + 1) * sizeof (symbase_t));
|
||
|
if ((hSymCl = MemAllocate (size)) == 0) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
pSymCl = (psymclass_t) MemLock (hSymCl);
|
||
|
memmove (pSymCl, pSymClass, size);
|
||
|
pSymCl->MaxIndex = (ulong )(pSymCl->CurIndex + 1);
|
||
|
pSymCl->hNext = pName->hFound;
|
||
|
pName->hFound = hSymCl;
|
||
|
pName->cFound++;
|
||
|
pSymClass->viable = FALSE;
|
||
|
MemUnLock (hSymCl);
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** FindIntro - find introducing virtual method
|
||
|
|
||
|
* status = FindIntro (pName)
|
||
|
|
||
|
* Entry pName = structure describing search
|
||
|
* pSymClass = structure describing class search
|
||
|
|
||
|
* Exit pSymClass updated to reflect introducing virtual method
|
||
|
|
||
|
* Returns SCN_found if introducing virtual method found
|
||
|
* SCN_error if introducing virtual method not found
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
FindIntro (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
ulong oldmask;
|
||
|
SCN_t retval;
|
||
|
bool_t fSupBaseSaved;
|
||
|
unsigned char cbNameSaved;
|
||
|
|
||
|
oldmask = pName->clsmask;
|
||
|
cbNameSaved = pName->sstr.cb;
|
||
|
fSupBaseSaved = pExState->state.fSupBase;
|
||
|
|
||
|
// CV400 #2863 look at all bases [rm]
|
||
|
pExState->state.fSupBase = FALSE;
|
||
|
|
||
|
// CV400 #2863
|
||
|
// destructor's don't have same name look only for the '~' [rm]
|
||
|
|
||
|
if (pName->sstr.lpName[0] == '~')
|
||
|
pName->sstr.cb = 1;
|
||
|
|
||
|
// limit searches to introducing virtual methods
|
||
|
// the CLS_vfunc is set so that we pick up the vfuncptr information
|
||
|
|
||
|
pName->clsmask = CLS_virtintro | CLS_vfunc | CLS_method;
|
||
|
retval = SearchBases (pName);
|
||
|
pName->clsmask = oldmask;
|
||
|
|
||
|
// restore name length and fSupBase [rm]
|
||
|
|
||
|
pExState->state.fSupBase = fSupBaseSaved;
|
||
|
pName->sstr.cb = cbNameSaved;
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*** GenQualName - generate qualified method name
|
||
|
|
||
|
* handle = GenQualName (pName, pSymClass)
|
||
|
|
||
|
* Entry pSymCLass = pointer to struct describing search
|
||
|
|
||
|
* Exit qualified function name generated
|
||
|
|
||
|
* Returns 0 if name string not generated
|
||
|
* handle if name string generated
|
||
|
*/
|
||
|
|
||
|
|
||
|
HDEP
|
||
|
GenQualName (
|
||
|
psearch_t pName,
|
||
|
psymclass_t pSymCl
|
||
|
)
|
||
|
{
|
||
|
HDEP hQual;
|
||
|
char *pQual;
|
||
|
uint buflen = 255;
|
||
|
uint len;
|
||
|
uint fSkip;
|
||
|
char *pField; // pointer to field list
|
||
|
HTYPE hBase; // handle to type record for base class
|
||
|
char *pc;
|
||
|
int i;
|
||
|
peval_t pL;
|
||
|
|
||
|
if ((hQual = MemAllocate (buflen + 1)) == 0) {
|
||
|
// unable to allocate memory
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (0);
|
||
|
}
|
||
|
pQual = (char *) MemLock (hQual);
|
||
|
memset (pQual, 0, 256);
|
||
|
|
||
|
// walk up list of search structures adding qualifiers
|
||
|
|
||
|
for (i = 0; i <= pSymCl->CurIndex; i++) {
|
||
|
if (CLASS_PROP (&pSymCl->symbase[i].Base).cnested != 0) {
|
||
|
NOTTESTED (FALSE);
|
||
|
}
|
||
|
if ((pSymCl->symbase[i].clsmask & CLS_virtintro) == CLS_virtintro) {
|
||
|
// if the search turned into a search for the introducing virtual
|
||
|
// function, break out of this loop so that the method name is
|
||
|
// correct
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
pL = &pSymCl->symbase[i].Base;
|
||
|
}
|
||
|
|
||
|
// copy name of last class encountered
|
||
|
|
||
|
if ((hBase = THGetTypeFromIndex (EVAL_MOD (pL), EVAL_TYP (pL))) == 0) {
|
||
|
pExState->err_num = ERR_INTERNAL;
|
||
|
return (0);
|
||
|
}
|
||
|
pField = (char *)(&((TYPPTR)MHOmfLock (hBase))->leaf);
|
||
|
switch (((plfClass)pField)->leaf) {
|
||
|
case LF_CLASS:
|
||
|
case LF_STRUCTURE:
|
||
|
fSkip = offsetof (lfClass, data);
|
||
|
RNumLeaf (pField + fSkip, &fSkip);
|
||
|
pc = pField + fSkip;
|
||
|
break;
|
||
|
|
||
|
case LF_UNION:
|
||
|
fSkip = offsetof (lfUnion, data);
|
||
|
RNumLeaf (pField + fSkip, &fSkip);
|
||
|
pc = pField + fSkip;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
DASSERT (FALSE);
|
||
|
MHOmfUnLock (hBase);
|
||
|
MemUnLock (hQual);
|
||
|
return (hQual);
|
||
|
}
|
||
|
len = *pc++;
|
||
|
if ((len + 2) <= buflen) {
|
||
|
memcpy (pQual, pc, len);
|
||
|
pQual += len;
|
||
|
*pQual++ = ':';
|
||
|
*pQual++ = ':';
|
||
|
buflen -= len + 2;
|
||
|
}
|
||
|
memcpy (pQual, pName->sstr.lpName, pName->sstr.cb);
|
||
|
MHOmfUnLock (hBase);
|
||
|
MemUnLock (hQual);
|
||
|
return (hQual);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** pvThisFromST - generate expression for null path to qualified name
|
||
|
|
||
|
* status = pvThisFromST (bnOp)
|
||
|
|
||
|
* Entry bnOp = node to add init expression to
|
||
|
|
||
|
* Exit qualified path expression generated
|
||
|
|
||
|
* Returns TRUE if expression generated
|
||
|
* FALSE if no memory
|
||
|
*/
|
||
|
|
||
|
|
||
|
bool_t
|
||
|
pvThisFromST (
|
||
|
bnode_t bnOp
|
||
|
)
|
||
|
{
|
||
|
uint len;
|
||
|
pnode_t Parent;
|
||
|
peval_t pvOp;
|
||
|
int diff;
|
||
|
|
||
|
if (ST == NULL) {
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
// we need to generate an expression tree attached to the operator node
|
||
|
// which will compute the null this pointer adjustment from ST. This
|
||
|
// routine is used for pClass->Class::member
|
||
|
|
||
|
len = sizeof (node_t) + sizeof (adjust_t);
|
||
|
if ((diff = pTree->size - pTree->node_next - len) < 0) {
|
||
|
if (!GrowETree ((uint) (-diff))) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (FALSE);
|
||
|
}
|
||
|
if (bnCxt != 0) {
|
||
|
// the context was pointing into the expression tree.
|
||
|
// since the expression tree could have been reallocated,
|
||
|
// we must recompute the context pointer
|
||
|
|
||
|
pCxt = SHpCXTFrompCXF ((PCXF)&((pnode_t)bnCxt)->v[0]);
|
||
|
}
|
||
|
}
|
||
|
pvOp = &bnOp->v[0];
|
||
|
EVAL_IS_MEMBER (pvOp) = TRUE;
|
||
|
MEMBER_THISEXPR (pvOp) = pTree->node_next;
|
||
|
Parent = NULL;
|
||
|
|
||
|
// now add the node that causes pvThis to be initialized with the
|
||
|
// value of ST.
|
||
|
|
||
|
AddETInit (Parent, EVAL_TYP (ST));
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** GenQualExpr - generate expression for path to qualified name
|
||
|
|
||
|
* status = GenQualExpr (pName)
|
||
|
|
||
|
* Entry pName = pointer to struct describing search
|
||
|
* pSymClass = pointer to class path structure
|
||
|
|
||
|
* Exit qualified path expression generated
|
||
|
|
||
|
* Returns SCN_found is expression generated
|
||
|
* SCN_error if no memory
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
GenQualExpr (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
int i;
|
||
|
peval_t pvOp;
|
||
|
uint len;
|
||
|
pnode_t Parent;
|
||
|
int diff;
|
||
|
peval_t pvB;
|
||
|
CV_typ_t btype;
|
||
|
UOFFSET off;
|
||
|
uint pvOff = 0;
|
||
|
|
||
|
// we need to generate an expression tree attached to the operator node
|
||
|
// which will compute the this pointer adjustment. The number
|
||
|
// of nodes is potentially the number of base classes + an
|
||
|
// initializer.
|
||
|
|
||
|
// M00OPTIMIZE - if the final base is a direct or indirect virtual base
|
||
|
// M00OPTIMIZE - of the inital class, then the entire expression can be
|
||
|
// M00OPTIMIZE - reduced to one node + the initializer
|
||
|
|
||
|
len = (pSymClass->CurIndex + 2) * (sizeof (node_t) + sizeof (adjust_t));
|
||
|
pvOp = &pName->bnOp->v[0];
|
||
|
if ((diff = pTree->size - pTree->node_next - len) < 0) {
|
||
|
if (((char *)(pName->pv) >= (char *)pTree) &&
|
||
|
((char *)(pName->pv) < ((char *)pTree) + pTree->size)) {
|
||
|
pvOff = (uint)(((char *)pName->pv) - ((char *)pTree));
|
||
|
}
|
||
|
if (!GrowETree ((uint) (-diff))) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
if (bnCxt != 0) {
|
||
|
// the context was pointing into the expression tree.
|
||
|
// since the expression tree could have been reallocated,
|
||
|
// we must recompute the context pointer
|
||
|
|
||
|
pCxt = SHpCXTFrompCXF ((PCXF)&((pnode_t)bnCxt)->v[0]);
|
||
|
}
|
||
|
if (pvOff != 0) {
|
||
|
pName->pv = (peval_t)(((char *)pTree) + pvOff);
|
||
|
}
|
||
|
pvOp = &pName->bnOp->v[0];
|
||
|
}
|
||
|
|
||
|
// walk the path backwards generating the expression required to do
|
||
|
// the adjustment. The backwards walk is because evaluation is depth
|
||
|
// first.
|
||
|
|
||
|
MEMBER_THISEXPR (pvOp) = pTree->node_next;
|
||
|
Parent = NULL;
|
||
|
for (i = pSymClass->CurIndex; i > 0; i--) {
|
||
|
pvB = &pSymClass->symbase[i].Base;
|
||
|
btype = EVAL_TYP (pvB);
|
||
|
off = pSymClass->symbase[i].thisadjust;
|
||
|
if (pSymClass->symbase[i].fVirtual == TRUE) {
|
||
|
Parent = AddETExpr (Parent, pSymClass->symbase[i].vbptr,
|
||
|
pSymClass->symbase[i].vbpoff, off, btype);
|
||
|
} else {
|
||
|
Parent = AddETConst (Parent, off, btype);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// add the first real adjustment if necessary. What is really happening
|
||
|
// here is that the the expression was of the form x.CLASS::member and
|
||
|
// we need an adjustment from the object to the start of the base class
|
||
|
|
||
|
pvB = &pSymClass->evalP;
|
||
|
btype = EVAL_TYP (pvB);
|
||
|
if ((EVAL_STATE (pvB) == EV_type) && EVAL_IS_CLASS (pvB)) {
|
||
|
Parent = AddETConst (Parent, pSymClass->offset, btype);
|
||
|
}
|
||
|
|
||
|
// now add the node that causes pvThis to be initialized with the
|
||
|
// value of ST.
|
||
|
|
||
|
pvB = &pSymClass->symbase[i].Base;
|
||
|
btype = EVAL_TYP (pvB);
|
||
|
Parent = AddETInit (Parent, btype);
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** GetArgType - get type of argument to function
|
||
|
|
||
|
* fSuccess = GetArgType (pvF, argn, ptype);
|
||
|
|
||
|
* Entry pvF = pointer to function description
|
||
|
* argn = argument index (0-based)
|
||
|
* ptype = pointer to location to store type
|
||
|
|
||
|
* Exit *ptype = type of argument
|
||
|
* *ptype = 0 if vararg
|
||
|
|
||
|
* Returns FARG_error if error
|
||
|
* FARG_none if no arguments
|
||
|
* FARG_vararg if varargs allowed
|
||
|
* FARG_exact if exact list
|
||
|
*/
|
||
|
|
||
|
|
||
|
farg_t
|
||
|
GetArgType (
|
||
|
peval_t pvF,
|
||
|
int argn,
|
||
|
CV_typ_t *type
|
||
|
)
|
||
|
{
|
||
|
HTYPE hList; // handle of the type list
|
||
|
plfArgList pList = NULL;
|
||
|
register farg_t retval;
|
||
|
|
||
|
if (FCN_PCOUNT (pvF) == 0) {
|
||
|
// there are no formals. We need to check for varargs
|
||
|
|
||
|
*type = 0;
|
||
|
if (FCN_VARARGS (pvF) == TRUE) {
|
||
|
return (FARG_vararg);
|
||
|
}
|
||
|
else {
|
||
|
return (FARG_none);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// set hList to the handle of the type list
|
||
|
|
||
|
if ((hList = THGetTypeFromIndex (EVAL_MOD (pvF), FCN_PINDEX (pvF))) == NULL) {
|
||
|
DASSERT (FALSE);
|
||
|
return (FARG_error);
|
||
|
}
|
||
|
if (argn >= FCN_PCOUNT (pvF) - 1) {
|
||
|
// this argument can possibly be a vararg.
|
||
|
|
||
|
if (FCN_VARARGS (pvF) == TRUE) {
|
||
|
*type = 0;
|
||
|
retval = FARG_vararg;
|
||
|
}
|
||
|
else if (argn > FCN_PCOUNT (pvF)) {
|
||
|
// varargs are not allowed and the maximum arg count is exceeded
|
||
|
retval = FARG_error;
|
||
|
}
|
||
|
else {
|
||
|
// varargs are not allowed and this is the last argument
|
||
|
pList = (plfArgList)(&((TYPPTR)MHOmfLock (hList))->leaf);
|
||
|
*type = pList->arg[argn];
|
||
|
retval = FARG_exact;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
// this is before the last argument so it cannot be a vararg
|
||
|
// load type list and store type of argument
|
||
|
|
||
|
pList = (plfArgList)(&((TYPPTR)MHOmfLock (hList))->leaf);
|
||
|
*type = pList->arg[argn];
|
||
|
retval = FARG_exact;
|
||
|
}
|
||
|
if (pList != NULL) {
|
||
|
MHOmfUnLock (hList);
|
||
|
}
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** VBSearched - check to see if virtual base hase already been searched
|
||
|
|
||
|
* flag = VBSearched (type)
|
||
|
|
||
|
* Entry type = type index of virtual base
|
||
|
|
||
|
* Exit none
|
||
|
|
||
|
* Returns TRUE if virtual base has already been searched
|
||
|
* FALSE if virtual base has not been searched
|
||
|
*/
|
||
|
|
||
|
|
||
|
bool_t
|
||
|
VBSearched (
|
||
|
CV_typ_t type
|
||
|
)
|
||
|
{
|
||
|
ulong i;
|
||
|
|
||
|
for (i = 0; i < pVBSearch->CurIndex; i++) {
|
||
|
if (pVBSearch->dom[i] == type) {
|
||
|
return (TRUE);
|
||
|
}
|
||
|
}
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** GrowTMList - grow TML
|
||
|
|
||
|
* fSuccess = GrowTMList (void)
|
||
|
|
||
|
* Entry pTMLbp = pointer to TML
|
||
|
* pTMList = pointer to TM list
|
||
|
|
||
|
* Exit TML grown
|
||
|
* pTMList = pointer to locked table
|
||
|
|
||
|
* Returns TRUE if table grown
|
||
|
* FALSE if out of memory
|
||
|
*/
|
||
|
|
||
|
|
||
|
bool_t
|
||
|
GrowTMList (
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
register bool_t retval = FALSE;
|
||
|
HDEP hTMList;
|
||
|
|
||
|
MemUnLock (pTMLbp->hTMList);
|
||
|
if ((hTMList = MemReAlloc (pTMLbp->hTMList,
|
||
|
(pTMLbp->cTMListMax + TMLISTCNT) * sizeof (HTM))) != 0) {
|
||
|
pTMLbp->hTMList = hTMList;
|
||
|
pTMLbp->cTMListMax += TMLISTCNT;
|
||
|
retval = TRUE;
|
||
|
}
|
||
|
// lock list to maintain lock/unlock synchronization
|
||
|
|
||
|
pTMList = (HDEP *) MemLock (pTMLbp->hTMList);
|
||
|
return (retval);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** IncrSymBase - increment symbase_t index and grow if necessary
|
||
|
|
||
|
* status = IncrSymbase ();
|
||
|
|
||
|
* Entry none
|
||
|
|
||
|
* Exit *pSymClass->CurIndex incremented
|
||
|
* pSymBase grown if necessary
|
||
|
|
||
|
* Returns SCN_found if pSymClass->CurIndex incremented
|
||
|
* SCN_error if unable to allocate memory for duplication
|
||
|
*/
|
||
|
|
||
|
|
||
|
SCN_t
|
||
|
IncrSymBase (
|
||
|
void
|
||
|
)
|
||
|
{
|
||
|
uint size;
|
||
|
HDEP hNew;
|
||
|
|
||
|
if (++pSymClass->CurIndex >= pSymClass->MaxIndex) {
|
||
|
size = sizeof (symclass_t) + (pSymClass->CurIndex + 5) * sizeof (symbase_t);
|
||
|
MemUnLock (hSymClass);
|
||
|
if ((hNew = MemReAlloc (hSymClass, size)) == 0) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
pSymClass = (psymclass_t) MemLock (hSymClass);
|
||
|
pSymClass->CurIndex--;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
hSymClass = hNew;
|
||
|
pSymClass = (psymclass_t) MemLock (hSymClass);
|
||
|
pSymClass->MaxIndex += 5;
|
||
|
}
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/** IsDominated - check to see of feature is dominated
|
||
|
|
||
|
* fStatus = IsDominated (pSymBest, pSymTest)
|
||
|
|
||
|
* Entry pName = structure describing search
|
||
|
* pSymClass = structure describing most recent class search
|
||
|
|
||
|
* Exit pName updated to reflect search
|
||
|
* pSymClass updated to unambiguous feature
|
||
|
|
||
|
* Returns DOM_replace if pSymBest is dominated by pSymTest
|
||
|
* DOM_keep if pSymBest is exactly equivalent to pSymTest
|
||
|
* DOM_ambiguous if pSymBest is equal to pSymTest
|
||
|
* DOM_keep if pSymTest is duplicate virtual base
|
||
|
*/
|
||
|
|
||
|
|
||
|
DOM_t
|
||
|
IsDominated (
|
||
|
psymclass_t pSymBest,
|
||
|
psymclass_t pSymTest
|
||
|
)
|
||
|
{
|
||
|
int i;
|
||
|
int j;
|
||
|
|
||
|
if (pSymBest->isdupvbase == TRUE) {
|
||
|
return (DOM_replace);
|
||
|
}
|
||
|
if (pSymTest->isdupvbase == TRUE) {
|
||
|
return (DOM_keep);
|
||
|
}
|
||
|
|
||
|
// check all of the base classes for a dominated virtual base
|
||
|
|
||
|
for (i = 0; i <= pSymBest->CurIndex; i++) {
|
||
|
if (pSymBest->symbase[i].fVirtual == TRUE) {
|
||
|
for (j = pVBDom->CurIndex; j >= 0; j--) {
|
||
|
if (pVBDom->dom[j] == EVAL_TYP (&pSymBest->symbase[i].Base)) {
|
||
|
return (DOM_replace);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
for (i = 0; i <= pSymTest->CurIndex; i++) {
|
||
|
if (pSymTest->symbase[i].fVirtual == TRUE) {
|
||
|
for (j = pVBDom->CurIndex; j >= 0; j--) {
|
||
|
if (pVBDom->dom[j] == EVAL_TYP (&pSymTest->symbase[i].Base)) {
|
||
|
return (DOM_keep);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// we have two paths to potentially two different features. We now check
|
||
|
// to see if the features are identical. This is done by checking for
|
||
|
// static data members that have identical addresses and types
|
||
|
|
||
|
if (!EVAL_IS_STMEMBER (&pSymBest->evalP) ||
|
||
|
!EVAL_IS_STMEMBER (&pSymTest->evalP) ||
|
||
|
(EVAL_TYP (&pSymBest->evalP) != EVAL_TYP (&pSymTest->evalP)) ||
|
||
|
(EVAL_SYM_SEG (&pSymBest->evalP) != EVAL_SYM_SEG (&pSymTest->evalP)) ||
|
||
|
(EVAL_SYM_OFF (&pSymBest->evalP) != EVAL_SYM_OFF (&pSymTest->evalP))) {
|
||
|
return (DOM_ambiguous);
|
||
|
}
|
||
|
return (DOM_keep);
|
||
|
}
|
||
|
|
||
|
|
||
|
/** IsIntroVirt - is this the introducing virtual method
|
||
|
* Entry mlist = type index of lf mfunc
|
||
|
* pvtabind = pointer to virtual function table index
|
||
|
|
||
|
* Exit *pvtabind = virtual fuction table index
|
||
|
|
||
|
* Returns TRUE if the introducing virtual method is found
|
||
|
* FALSE otherwise
|
||
|
*/
|
||
|
bool_t
|
||
|
IsIntroVirt(
|
||
|
CV_typ_t tiMfunc
|
||
|
)
|
||
|
{
|
||
|
HTYPE hMethod;
|
||
|
HMOD hMod;
|
||
|
bool_t retval;
|
||
|
peval_t pvF;
|
||
|
plfMFunc pMFunc;
|
||
|
|
||
|
pvF = &pSymClass->evalP;
|
||
|
hMod = EVAL_MOD (pvF);
|
||
|
|
||
|
if ((hMethod = THGetTypeFromIndex (hMod, tiMfunc)) == NULL) {
|
||
|
DASSERT (FALSE);
|
||
|
return (FALSE);
|
||
|
}
|
||
|
pMFunc = (plfMFunc)((&((TYPPTR)MHOmfLock (hMethod))->leaf));
|
||
|
retval = (pMFunc->rvtype == FCN_RETURN (pvF)) &&
|
||
|
(pMFunc->arglist == FCN_PINDEX (pvF));
|
||
|
MHOmfUnLock (hMethod);
|
||
|
return retval == TRUE;
|
||
|
}
|
||
|
|
||
|
/** IsIntroVirtInMlist - is this the introducing virtual method in this mlist
|
||
|
|
||
|
* fSuccess = IsIntroVirtInMlist (count, mlist, pvtabindex)
|
||
|
|
||
|
* Entry count = number of methods in list
|
||
|
* mlist = type index of method list
|
||
|
* pvtabind = pointer to virtual function table index
|
||
|
|
||
|
* Exit *pvtabind = virtual fuction table index
|
||
|
|
||
|
* Returns TRUE if the introducing virtual method is found
|
||
|
* FALSE otherwise
|
||
|
*/
|
||
|
|
||
|
|
||
|
bool_t
|
||
|
IsIntroVirtInMlist(
|
||
|
ulong count,
|
||
|
CV_typ_t mlist,
|
||
|
UOFFSET *pvtabind
|
||
|
)
|
||
|
{
|
||
|
HTYPE hMethod;
|
||
|
pmlMethod pMethod;
|
||
|
uint cbSkip;
|
||
|
bool_t Mmatch = 0;
|
||
|
peval_t pvF;
|
||
|
HMOD hMod;
|
||
|
|
||
|
pvF = &pSymClass->evalP;
|
||
|
hMod = EVAL_MOD (pvF);
|
||
|
|
||
|
// we now walk the list of methods looking for a method with the same
|
||
|
// return type and argument list type
|
||
|
|
||
|
if ((hMethod = THGetTypeFromIndex (hMod, mlist)) == NULL) {
|
||
|
DASSERT (FALSE);
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
// set the number of methods overloaded on this name and the index into
|
||
|
// the method list
|
||
|
|
||
|
cbSkip = 0;
|
||
|
*pvtabind = 0;
|
||
|
|
||
|
while (count-- > 0) {
|
||
|
// lock the omf record, extract information for the current entry in
|
||
|
// the method list and increment to field for next method
|
||
|
|
||
|
plfMethodList plfMList;
|
||
|
|
||
|
plfMList = (plfMethodList) &((TYPPTR) MHOmfLock(hMethod))->leaf;
|
||
|
pMethod = (pmlMethod) &plfMList->mList[cbSkip];
|
||
|
|
||
|
cbSkip += sizeof (mlMethod);
|
||
|
if (fIntroducingVirtual(pMethod->attr.mprop)) {
|
||
|
cbSkip += sizeof(pMethod->vbaseoff[0]);
|
||
|
if (IsIntroVirt(pMethod->index)) {
|
||
|
*pvtabind = pMethod->vbaseoff[0];
|
||
|
MHOmfUnLock(hMethod);
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
MHOmfUnLock (hMethod);
|
||
|
}
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/** MatchArgs - match a method against argument list
|
||
|
|
||
|
* flag = MatchArgs (pv, pName, fattr, vtabind, fForce)
|
||
|
|
||
|
* Entry pv = pointer to function descriptor
|
||
|
* pName = pointer to search structure
|
||
|
* attr = attribute if method
|
||
|
* vtabind = offset into vtable if virtual method
|
||
|
* fForce = TRUE if match on first (only) method is forced
|
||
|
* This is the case if bp method, no args and single
|
||
|
* method.
|
||
|
* BindingBP = TRUE if call is via ParseBP API entry
|
||
|
* if BindingBP is true, then only exact matches are allowed
|
||
|
* bArgList = based pointer to argument list
|
||
|
|
||
|
* Exit ST = resolved address of method
|
||
|
|
||
|
* Returns TRUE if a match was found or ambiguous references are allowed
|
||
|
* FALSE if no match or ambiguity not allowed
|
||
|
*/
|
||
|
|
||
|
|
||
|
void
|
||
|
MatchArgs (
|
||
|
peval_t pvM,
|
||
|
psearch_t pName,
|
||
|
CV_fldattr_t attr,
|
||
|
UOFFSET vtabind,
|
||
|
bool_t fForce
|
||
|
)
|
||
|
{
|
||
|
pnode_t pnT;
|
||
|
pargd_t pa;
|
||
|
bool_t update = FALSE;
|
||
|
argcounters current;
|
||
|
int argc;
|
||
|
CV_typ_t Ftype;
|
||
|
bool_t argmatch;
|
||
|
eval_t evalArg;
|
||
|
peval_t pvArg = &evalArg;
|
||
|
|
||
|
// walk down the formal list specified by pvM and the actual list
|
||
|
// specified by bArgList. Initialize the conversion counters to
|
||
|
// zero and set the index to varargs parameter to zero
|
||
|
|
||
|
argc = 0;
|
||
|
current.exact = 0;
|
||
|
current.implicit = 0;
|
||
|
current.varargs = 0;
|
||
|
argmatch = FALSE;
|
||
|
pnT = (pnode_t)bArgList;
|
||
|
|
||
|
(pName->overloadCount)++;
|
||
|
if (fForce == TRUE) {
|
||
|
argmatch = TRUE;
|
||
|
update = TRUE;
|
||
|
}
|
||
|
else if (!N_EVAL_IS_FCN(pvM)) {
|
||
|
argmatch = TRUE;
|
||
|
current.exact = 0;
|
||
|
}
|
||
|
else while (TRUE) {
|
||
|
if (NODE_OP (pnT) == OP_endofargs) {
|
||
|
if ((argc == FCN_PCOUNT (pvM)) ||
|
||
|
((argc >= (FCN_PCOUNT (pvM) - 1)) && (FCN_VARARGS (pvM) == TRUE))) {
|
||
|
argmatch = TRUE;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
if ((argc > FCN_PCOUNT (pvM)) && (FCN_VARARGS (pvM) == FALSE)) {
|
||
|
// this function cannot possibly be a match because the
|
||
|
// number of actuals is greater than the number of formals
|
||
|
// and the method does not allow varargs.
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
// pa points to the argument descriptor array in the OP_arg node
|
||
|
pa = (pargd_t)&(pnT->v[0]);
|
||
|
switch (GetArgType (pvM, argc, &Ftype)) {
|
||
|
case FARG_error:
|
||
|
DASSERT (FALSE);
|
||
|
return;
|
||
|
|
||
|
case FARG_none:
|
||
|
// special case foo(void)
|
||
|
// sps 2/20/92
|
||
|
if ((argc == 0) && (pa->actual == T_VOID)) {
|
||
|
argmatch = TRUE;
|
||
|
goto argmatchloop;
|
||
|
}
|
||
|
return;
|
||
|
|
||
|
case FARG_vararg:
|
||
|
// varargs are allowed unless we are binding breakpoints
|
||
|
if (BindingBP == TRUE) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case FARG_exact:
|
||
|
if ((argc + 1) > FCN_PCOUNT (pvM)) {
|
||
|
// we must exactly match the argument count and we
|
||
|
// have more arguments
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
argc++;
|
||
|
|
||
|
|
||
|
if (Ftype == 0) {
|
||
|
// all arguments from this point on are vararg
|
||
|
current.varargs = argc;
|
||
|
pa->current = OM_vararg;
|
||
|
}
|
||
|
else {
|
||
|
CV_typ_t Atype = pa->actual;
|
||
|
eval_t vA, vF;
|
||
|
peval_t pvA = &vA;
|
||
|
peval_t pvF = &vF;
|
||
|
|
||
|
if (pa->flags.istype) {
|
||
|
// If we have a type want identical type indices
|
||
|
// (This helps with class dumps)
|
||
|
#if CC_LAZYTYPES
|
||
|
if ( THAreTypesEqual( EVAL_MOD( pvM ), Atype, Ftype ) )
|
||
|
#else
|
||
|
if ( Atype == Ftype )
|
||
|
#endif
|
||
|
{
|
||
|
current.exact++;
|
||
|
pa->current = OM_exact;
|
||
|
pnT = (pnode_t)NODE_RCHILD (pnT);
|
||
|
continue;
|
||
|
}
|
||
|
else {
|
||
|
pExState->err_num = ERR_NONE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Ftype = SkipModifiers(EVAL_MOD(pvM), Ftype);
|
||
|
Atype = SkipModifiers(EVAL_MOD(pvM), Atype);
|
||
|
|
||
|
*pvF = *pvM;
|
||
|
if (!SetNodeType(pvF, Ftype)) {
|
||
|
// error (not valid type)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// Update Ftype (SetNodeType must have resolved potential fwd refs)
|
||
|
Ftype = EVAL_TYP (pvF);
|
||
|
|
||
|
// if we are calling a 32 bit func we must promote all const
|
||
|
// int2's to int4's
|
||
|
|
||
|
if (EVAL_SYM_IS32(pvM) &&
|
||
|
(EVAL_STATE((peval_t)(&((pnode_t)NODE_LCHILD (pnT))->v[0])) == EV_constant) &&
|
||
|
((Atype == T_INT2) || (Atype == T_UINT2))
|
||
|
) {
|
||
|
Atype++;
|
||
|
}
|
||
|
|
||
|
*pvA = *pvM;
|
||
|
if (!SetNodeType(pvA, Atype)) {
|
||
|
// error (not valid type)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (EVAL_IS_PTR(pvA) && EVAL_IS_REF(pvA)) {
|
||
|
Atype = SkipModifiers(EVAL_MOD(pvM), PTR_UTYPE(pvA));
|
||
|
}
|
||
|
|
||
|
#if CC_LAZYTYPES
|
||
|
if ( THAreTypesEqual( EVAL_MOD( pvM ), Atype, Ftype ) )
|
||
|
#else
|
||
|
if (Atype == Ftype)
|
||
|
#endif
|
||
|
{
|
||
|
current.exact++;
|
||
|
pa->current = OM_exact;
|
||
|
pnT = (pnode_t)NODE_RCHILD (pnT);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (EVAL_IS_PTR(pvF)) {
|
||
|
*pvA = *pvM;
|
||
|
if (!SetNodeType(pvA, Atype)) {
|
||
|
// error (not valid type)
|
||
|
break;
|
||
|
}
|
||
|
if (!EVAL_IS_REF(pvF)) {
|
||
|
if (!EVAL_IS_PTR(pvA)) {
|
||
|
// do not cast a non-pointer to pointer
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
PTR_UTYPE(pvA) = SkipModifiers(EVAL_MOD(pvM), PTR_UTYPE(pvA));
|
||
|
PTR_UTYPE(pvF) = SkipModifiers(EVAL_MOD(pvM), PTR_UTYPE(pvF));
|
||
|
|
||
|
if (EVAL_PTRTYPE(pvA) == EVAL_PTRTYPE(pvF) &&
|
||
|
#if CC_LAZYTYPES
|
||
|
THAreTypesEqual( EVAL_MOD( pvA ), PTR_UTYPE(pvA), PTR_UTYPE(pvA) ) &&
|
||
|
#else
|
||
|
PTR_UTYPE(pvA) == PTR_UTYPE(pvF) &&
|
||
|
#endif
|
||
|
!EVAL_IS_BASED(pvA) &&
|
||
|
!EVAL_IS_BASED(pvF)) {
|
||
|
|
||
|
// we don't match based pointers. if we want to
|
||
|
// do this we must examine additional information
|
||
|
// we allow mathcing a pointer with an array
|
||
|
// however all arrays are considered far
|
||
|
// since codeview information does not distinguish
|
||
|
// between far or near arrays. --gdp 10/16/92
|
||
|
|
||
|
current.exact++;
|
||
|
pa->current = OM_exact;
|
||
|
pnT = (pnode_t)NODE_RCHILD (pnT);
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
|
||
|
// special handling of a reference
|
||
|
|
||
|
|
||
|
CV_typ_t Utype;
|
||
|
|
||
|
Utype = SkipModifiers(EVAL_MOD(pvM), PTR_UTYPE (pvF));
|
||
|
#if CC_LAZYTYPES
|
||
|
if ( THAreTypesEqual( EVAL_MOD( pvM ), Utype, Atype ) )
|
||
|
#else
|
||
|
if (Utype == Atype)
|
||
|
#endif
|
||
|
{
|
||
|
current.exact++;
|
||
|
pa->current = OM_exact;
|
||
|
pnT = (pnode_t)NODE_RCHILD (pnT);
|
||
|
continue;
|
||
|
}
|
||
|
else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
// see if we can cast the type of the actual to the type of
|
||
|
// the formal if we are not binding breakpoints. If we are
|
||
|
// binding breakpoints, only exact matches are allowed
|
||
|
|
||
|
*pvArg = *pvM;
|
||
|
SetNodeType (pvArg, pa->actual);
|
||
|
if (EVAL_IS_BITF (pvArg)) {
|
||
|
SetNodeType (pvArg, BITF_UTYPE (pvArg));
|
||
|
}
|
||
|
if (CastNode (pvArg, Ftype, Ftype)) {
|
||
|
pa->current = OM_implicit;
|
||
|
current.implicit++;
|
||
|
}
|
||
|
else {
|
||
|
pExState->err_num = ERR_NONE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
pnT = (pnode_t)NODE_RCHILD (pnT);
|
||
|
}
|
||
|
argmatchloop:
|
||
|
if (argmatch == TRUE) {
|
||
|
// check current against best match
|
||
|
|
||
|
if (pName->best.match == 0) {
|
||
|
// we have a first time match
|
||
|
update = TRUE;
|
||
|
pName->possibles++;
|
||
|
}
|
||
|
else if (fForce == FALSE) {
|
||
|
// we have already matched on some function so we now
|
||
|
// check to see if the current is better than the best
|
||
|
if (current.varargs == 0) {
|
||
|
// there are no varargs in this method therefor it is
|
||
|
// better than any previous match with varargs
|
||
|
if (pName->best.varargs != 0) {
|
||
|
update = TRUE;
|
||
|
pName->best = current;
|
||
|
pName->possibles = 1;
|
||
|
}
|
||
|
else if (current.exact > pName->best.exact) {
|
||
|
// this function has more exact matches than the
|
||
|
// best one so far
|
||
|
update = TRUE;
|
||
|
pName->possibles = 1;
|
||
|
}
|
||
|
#if CC_LAZYTYPES
|
||
|
else if ( !THAreTypesEqual( EVAL_MOD( pvM ), EVAL_TYP (pvM), pName->best.match ) &&
|
||
|
#else
|
||
|
else if (EVAL_TYP (pvM) != pName->best.match &&
|
||
|
#endif
|
||
|
current.exact == pName->best.exact) {
|
||
|
// this function is a good as the best one.
|
||
|
// this means the call is ambiguous
|
||
|
pName->possibles++;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if (pName->best.varargs != 0) {
|
||
|
// both the current and the best functions have
|
||
|
// varargs
|
||
|
|
||
|
if (current.varargs < pName->best.varargs) {
|
||
|
// this function uses fewer varargs which
|
||
|
// makes it a better one
|
||
|
update = TRUE;
|
||
|
pName->possibles = 1;
|
||
|
}
|
||
|
else if (current.varargs == pName->best.varargs) {
|
||
|
// this function uses the same number of varargs
|
||
|
// pick the one with more exact matches
|
||
|
if (current.exact > pName->best.exact) {
|
||
|
update = TRUE;
|
||
|
pName->possibles = 1;
|
||
|
}
|
||
|
#if CC_LAZYTYPES
|
||
|
else if ( !THAreTypesEqual( EVAL_MOD( pvM ), EVAL_TYP (pvM), pName->best.match ) &&
|
||
|
#else
|
||
|
else if (EVAL_TYP (pvM) != pName->best.match &&
|
||
|
#endif
|
||
|
current.exact == pName->best.exact) {
|
||
|
pName->possibles++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (update == TRUE) {
|
||
|
if (fForce == FALSE) {
|
||
|
// the current match is better
|
||
|
for (pnT = (pnode_t)bArgList; NODE_OP (pnT) != OP_endofargs; pnT = (pnode_t)NODE_RCHILD (pnT)) {
|
||
|
pa = (pargd_t)&(pnT->v[0]);
|
||
|
pa->best = pa->current;
|
||
|
}
|
||
|
{ //M00KLUDGE - hack for compiler DS != SS bug
|
||
|
argcounters *pcurrent = ¤t;
|
||
|
pName->best = *pcurrent;
|
||
|
}
|
||
|
}
|
||
|
pName->best.match = EVAL_TYP (pvM);
|
||
|
pName->best.attr = attr;
|
||
|
pName->best.vtabind = vtabind;
|
||
|
pName->best.hSym = pName->hSym;
|
||
|
pName->best.CXTT = pName->CXTT;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
CV_typ_t
|
||
|
SkipModifiers(
|
||
|
HMOD mod,
|
||
|
CV_typ_t type
|
||
|
)
|
||
|
{
|
||
|
HTYPE hType;
|
||
|
plfModifier pType;
|
||
|
|
||
|
if (!CV_IS_PRIMITIVE (type)) {
|
||
|
hType = THGetTypeFromIndex (mod, type);
|
||
|
pType = (plfModifier)((&((TYPPTR)MHOmfLock (hType))->leaf));
|
||
|
while (pType->leaf == LF_MODIFIER) {
|
||
|
type = pType->type;
|
||
|
if (CV_IS_PRIMITIVE (type)) {
|
||
|
break;
|
||
|
}
|
||
|
MHOmfUnLock (hType);
|
||
|
hType = THGetTypeFromIndex (mod, type);
|
||
|
pType = (plfModifier)((&((TYPPTR)MHOmfLock (hType))->leaf));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MHOmfUnLock (hType);
|
||
|
return type;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/** MatchFunction - match a function against argument list
|
||
|
|
||
|
* flag = MatchFunction (pName)
|
||
|
|
||
|
* Entry pName = pointer to search status
|
||
|
* BindingBP = TRUE if call is via ParseBP API entry
|
||
|
* bArgList = based pointer to argument list
|
||
|
|
||
|
* Exit pv = resolved address of method
|
||
|
|
||
|
* Returns HR_... describing match result
|
||
|
*/
|
||
|
|
||
|
|
||
|
HR_t FASTCALL
|
||
|
MatchFunction (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
HR_t retval;
|
||
|
CV_fldattr_t attr = {0};
|
||
|
CV_typ_t type;
|
||
|
ADDR addr = {0};
|
||
|
bool_t dupfcn;
|
||
|
|
||
|
if (bArgList == NULL) {
|
||
|
// if there is no argument list, assume we are assigning to a
|
||
|
// function pointer and take the first function found. Let the
|
||
|
// user beware.
|
||
|
|
||
|
return (HR_found);
|
||
|
}
|
||
|
|
||
|
// save the function address and type. Then if a subsequent match has
|
||
|
// the same address and type (i.e., comdat code), we can ignore it.
|
||
|
|
||
|
addr = EVAL_SYM (ST);
|
||
|
type = EVAL_TYP (ST);
|
||
|
|
||
|
// pop the entry that SearchSym has added to the evaluation stack
|
||
|
// the best match will be pushed back on later
|
||
|
|
||
|
pName->scope |= SCP_nomatchfn;
|
||
|
|
||
|
PopStack ();
|
||
|
MatchArgs (pName->pv, pName, attr, 0, FALSE);
|
||
|
while ((retval = SearchSym (pName)) != HR_notfound) {
|
||
|
DASSERT (retval != HR_end);
|
||
|
dupfcn = FALSE;
|
||
|
if (retval == HR_found) {
|
||
|
// Mips publics for C functions are not decorated so don't
|
||
|
// bother with type-check, just see if the addresses are the same
|
||
|
if (memcmp (&addr, &EVAL_SYM (ST), sizeof (addr)) == 0) {
|
||
|
dupfcn = TRUE;
|
||
|
}
|
||
|
PopStack ();
|
||
|
if (dupfcn == FALSE) {
|
||
|
MatchArgs (pName->pv, pName, attr, 0, FALSE);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
return (retval);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pName->scope &= ~SCP_nomatchfn;
|
||
|
|
||
|
// clear the symbol not found error from the recursive symbol search
|
||
|
|
||
|
pExState->err_num = ERR_NONE;
|
||
|
if (pName->best.match == 0) {
|
||
|
pExState->err_num = ERR_ARGLIST;
|
||
|
return (HR_error);
|
||
|
}
|
||
|
else if (pName->possibles > 1) {
|
||
|
PushStack (pName->pv);
|
||
|
pExState->err_num = ERR_AMBIGUOUS;
|
||
|
EVAL_IS_AMBIGUOUS (ST) = TRUE;
|
||
|
return (HR_ambiguous);
|
||
|
}
|
||
|
else if (pName->overloadCount > 1 && pName->best.implicit > 0) {
|
||
|
|
||
|
// overloaded function that involves implicit casts
|
||
|
|
||
|
pExState->err_num = ERR_AMBIGUOUS;
|
||
|
return (HR_ambiguous);
|
||
|
}
|
||
|
else {
|
||
|
pName->hSym = pName->best.hSym;
|
||
|
pName->CXTT = pName->best.CXTT;
|
||
|
if ((SymToNode (pName) == FALSE) || (PushStack (pName->pv) == FALSE)) {
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
else {
|
||
|
return (HR_found);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** MatchMethod - match a method against argument list
|
||
|
|
||
|
* flag = MatchMethod (pName, pSymCl)
|
||
|
|
||
|
* Entry pName = pointer to search descriptor
|
||
|
* pSymCl = pointer tp symbol class structure
|
||
|
* select = selection masj
|
||
|
* BindingBP = TRUE if call is via ParseBP API entry
|
||
|
* if BindingBP is true, then only exact matches allowed
|
||
|
* bArgList = based pointer to argument list
|
||
|
|
||
|
* Exit pName->pv = resolved address of method
|
||
|
|
||
|
* Returns MTH_found if a match was found or ambiguous references are allowed
|
||
|
* MTH_error if error or ambiguity not allowed
|
||
|
|
||
|
*/
|
||
|
|
||
|
|
||
|
static bool_t
|
||
|
setupMatchArgs(
|
||
|
psearch_t pName,
|
||
|
CV_fldattr_t attr,
|
||
|
UOFFSET vtabind,
|
||
|
bool_t fForce,
|
||
|
CV_typ_t type,
|
||
|
HMOD hMod
|
||
|
)
|
||
|
{
|
||
|
eval_t evalM;
|
||
|
peval_t pvM = &evalM;
|
||
|
// now compare the actual and formal argument lists for the function
|
||
|
// pvM will be initialized to be a function node whose type index is
|
||
|
// type.
|
||
|
|
||
|
CLEAR_EVAL (pvM);
|
||
|
EVAL_MOD (pvM) = hMod;
|
||
|
if (SetNodeType (pvM, type) == FALSE) {
|
||
|
// the type record for the method was not found
|
||
|
DASSERT (FALSE);
|
||
|
return FALSE;
|
||
|
}
|
||
|
MatchArgs (pvM, pName, attr, vtabind, fForce);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
MTH_t
|
||
|
MatchMethod (
|
||
|
psearch_t pName,
|
||
|
psymclass_t pSymCl
|
||
|
)
|
||
|
{
|
||
|
HTYPE hMethod;
|
||
|
pmlMethod pMethod;
|
||
|
uint skip;
|
||
|
CV_fldattr_t attr;
|
||
|
CV_typ_t type;
|
||
|
UOFFSET vtabind;
|
||
|
bool_t Mmatch = 0;
|
||
|
HDEP hQual;
|
||
|
peval_t pvF;
|
||
|
ulong count = pSymCl->possibles;
|
||
|
peval_t pvB;
|
||
|
HMOD hMod;
|
||
|
bool_t fForce = FALSE;
|
||
|
TYPPTR ptype;
|
||
|
|
||
|
pvB = &pSymClass->symbase[pSymClass->CurIndex].Base;
|
||
|
hMod = EVAL_MOD (pvB);
|
||
|
pName->possibles = 0;
|
||
|
pvF = &pSymCl->evalP;
|
||
|
|
||
|
// we now walk the list of methods looking for an argument match
|
||
|
// For now, we require an exact match except that we assume any
|
||
|
// primitive type can be cast to any other primitive type. A cast from
|
||
|
// pointer to derived to pointer to base is an implicit conversion
|
||
|
|
||
|
if ((hMethod = THGetTypeFromIndex (hMod, pSymCl->mlist)) == NULL) {
|
||
|
DASSERT (FALSE);
|
||
|
return (MTH_error);
|
||
|
}
|
||
|
|
||
|
// set the number of methods overloaded on this name and the index into
|
||
|
// the method list
|
||
|
|
||
|
skip = 0;
|
||
|
if (bArgList == NULL) {
|
||
|
if (count == 1) {
|
||
|
fForce = TRUE;
|
||
|
}
|
||
|
else {
|
||
|
// there is not an argument list. We allow breakpoints if a single
|
||
|
// method by that name exists. Otherwise, we require an argument
|
||
|
// list
|
||
|
|
||
|
pExState->err_num = ERR_NOARGLIST;
|
||
|
return (MTH_error);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ptype = (TYPPTR)MHOmfLock (hMethod);
|
||
|
if (ptype->leaf == LF_METHODLIST) {
|
||
|
MHOmfUnLock (hMethod);
|
||
|
while (count-- > 0) {
|
||
|
// lock the omf record, extract information for the current entry in
|
||
|
// the method list and increment to field for next method
|
||
|
|
||
|
pMethod = (pmlMethod)((&((TYPPTR)MHOmfLock (hMethod))->leaf) + 1);
|
||
|
pMethod = (pmlMethod)((uchar *)pMethod + skip);
|
||
|
attr = pMethod->attr;
|
||
|
type = pMethod->index;
|
||
|
skip += sizeof (mlMethod);
|
||
|
if (fIntroducingVirtual(pMethod->attr.mprop)) {
|
||
|
vtabind = pMethod->vbaseoff[0];
|
||
|
skip += sizeof(pMethod->vbaseoff[0]);
|
||
|
}
|
||
|
else {
|
||
|
vtabind = 0;
|
||
|
}
|
||
|
MHOmfUnLock (hMethod);
|
||
|
if (!setupMatchArgs(pName, attr, vtabind, fForce, type, hMod))
|
||
|
return (MTH_error);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
DASSERT(ptype->leaf == LF_MFUNCTION);
|
||
|
DASSERT(count <= 1);
|
||
|
MHOmfUnLock (hMethod);
|
||
|
if (!setupMatchArgs(pName, pSymCl->access, FCN_VTABIND (pvF) , fForce, pSymCl->mlist, hMod))
|
||
|
return (MTH_error);
|
||
|
}
|
||
|
|
||
|
// since the name was found at this level, it hides all other methods
|
||
|
// by the same name above it in the inheritance tree. Therefore we must
|
||
|
// either have a match or an error because there is no match or two or
|
||
|
// methods match after conversions are considered
|
||
|
|
||
|
if (pName->best.match == 0) {
|
||
|
pExState->err_num = ERR_ARGLIST;
|
||
|
return (MTH_error);
|
||
|
}
|
||
|
else if (pName->possibles > 1) {
|
||
|
pExState->err_num = ERR_AMBIGUOUS;
|
||
|
EVAL_IS_AMBIGUOUS (pName->pv) = TRUE;
|
||
|
return (MTH_error);
|
||
|
}
|
||
|
else if (pName->overloadCount > 1 && pName->best.implicit > 0) {
|
||
|
// we have an overloaded method
|
||
|
// in this case the EE requires exact matches only
|
||
|
pExState->err_num = ERR_AMBIGUOUS;
|
||
|
EVAL_IS_AMBIGUOUS (pName->pv) = TRUE;
|
||
|
return (MTH_error);
|
||
|
}
|
||
|
else {
|
||
|
// we have found a non-ambiguous match
|
||
|
|
||
|
EVAL_MOD (pvF) = hMod;
|
||
|
if (SetNodeType (pvF, pName->best.match) == FALSE) {
|
||
|
return (MTH_error);
|
||
|
}
|
||
|
else {
|
||
|
pSymCl->access.access = pName->best.attr.access;
|
||
|
FCN_ATTR (pvF) = pName->best.attr;
|
||
|
FCN_VTABIND (pvF) = pName->best.vtabind;
|
||
|
FCN_VFPTYPE (pvF) = pSymCl->vfpType;
|
||
|
if (NODE_OP (pName->bnOp) == OP_bscope) {
|
||
|
// binary scoping switches off virtual function evaluation
|
||
|
FCN_PROPERTY (pvF) = CV_MTvanilla;
|
||
|
}
|
||
|
if ((FCN_PROPERTY (pvF) == CV_MTvirtual) ||
|
||
|
(FCN_PROPERTY (pvF) == CV_MTintro)) {
|
||
|
// do nothing. address will have to be found at evaluation
|
||
|
}
|
||
|
else {
|
||
|
if (((hQual = GenQualName (pName, pSymClass)) == 0) ||
|
||
|
(SearchQualName (pName, pSymCl, hQual, TRUE) == FALSE)) {
|
||
|
if (hQual != 0) {
|
||
|
MemFree (hQual);
|
||
|
}
|
||
|
return (MTH_error);
|
||
|
}
|
||
|
MemFree (hQual);
|
||
|
}
|
||
|
return (MTH_found);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/** MoveSymCl - move symbol class structure
|
||
|
|
||
|
* MoveSymCl (hSymCl);
|
||
|
|
||
|
* Entry hSymCl = handle of symbol class structure
|
||
|
|
||
|
* Exit *pSymClass = symbol class structure
|
||
|
|
||
|
* Returns none
|
||
|
*/
|
||
|
|
||
|
void
|
||
|
MoveSymCl (
|
||
|
HDEP hSymCl
|
||
|
)
|
||
|
{
|
||
|
psymclass_t pSymCl;
|
||
|
ulong max;
|
||
|
|
||
|
pSymCl = (psymclass_t) MemLock (hSymCl);
|
||
|
DASSERT (pSymClass->MaxIndex >= pSymCl->CurIndex);
|
||
|
max = pSymClass->MaxIndex;
|
||
|
memmove (pSymClass, pSymCl,
|
||
|
sizeof (symclass_t) + (pSymCl->CurIndex + 1) * sizeof (symbase_t));
|
||
|
pSymClass->MaxIndex = max;
|
||
|
MemUnLock (hSymCl);
|
||
|
MemFree (hSymCl);
|
||
|
}
|
||
|
|
||
|
|
||
|
/** PurgeAmbCl - purge ambiguous class structure list
|
||
|
|
||
|
* PurgeAmbCl (pName)
|
||
|
|
||
|
* Entry pName = pointer to symbol search structure
|
||
|
|
||
|
* Exit pname->hAmb list freed
|
||
|
|
||
|
* Returns none
|
||
|
*/
|
||
|
|
||
|
void
|
||
|
PurgeAmbCl (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
psymclass_t pAmbCl;
|
||
|
HDEP hNext;
|
||
|
|
||
|
while (pName->hAmbCl != 0) {
|
||
|
pAmbCl = (psymclass_t) MHMemLock (pName->hAmbCl);
|
||
|
hNext = pAmbCl->hNext;
|
||
|
MHMemUnLock (pName->hAmbCl);
|
||
|
pName->hAmbCl = hNext;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*** SetBase - set base value in pSymClass->symbase array
|
||
|
|
||
|
* status = SetBase (pName, type, vbptr, vbpoff, thisadjust, attr, virtual)
|
||
|
|
||
|
* Entry pName = pointer to struct describing search
|
||
|
* type = type index of class
|
||
|
* vbptr = type index of virtual base pointer
|
||
|
* vbpoff = offset of virtual base pointer from address point
|
||
|
* thisadjust = offset of base from previous class
|
||
|
* thisadjust = virtual base index if virtual base
|
||
|
* attr = field attribute mask
|
||
|
* virtual = TRUE if virtual base
|
||
|
|
||
|
* Exit new base class added to pSymClass
|
||
|
|
||
|
* Returns enum describing search state
|
||
|
*/
|
||
|
|
||
|
SCN_t
|
||
|
SetBase (
|
||
|
psearch_t pName,
|
||
|
CV_typ_t type,
|
||
|
CV_typ_t vbptr,
|
||
|
UOFFSET vbpoff,
|
||
|
UOFFSET thisadjust,
|
||
|
CV_fldattr_t attr,
|
||
|
bool_t fVirtual
|
||
|
)
|
||
|
{
|
||
|
peval_t pvB;
|
||
|
|
||
|
// save offset of base from address point for this pointer adjustment
|
||
|
|
||
|
pSymClass->symbase[pSymClass->CurIndex].thisadjust = thisadjust;
|
||
|
pSymClass->symbase[pSymClass->CurIndex].vbptr = vbptr;
|
||
|
pSymClass->symbase[pSymClass->CurIndex].vbpoff = vbpoff;
|
||
|
pSymClass->symbase[pSymClass->CurIndex].attrBC = attr;
|
||
|
pSymClass->symbase[pSymClass->CurIndex].fVirtual = fVirtual;
|
||
|
pSymClass->symbase[pSymClass->CurIndex].clsmask = pName->clsmask;
|
||
|
pvB = &pSymClass->symbase[pSymClass->CurIndex].Base;
|
||
|
EVAL_MOD (pvB) = pName->hMod;
|
||
|
EVAL_CXTT(pvB) = pName->CXTT;
|
||
|
if (SetNodeType (pvB, type) == FALSE) {
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (SCN_error);
|
||
|
}
|
||
|
return (SCN_found);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*** SearchQualName - Search for a qualified method name
|
||
|
|
||
|
* flag = SearchQualName (pName, pSymCl, hQual, fProc)
|
||
|
|
||
|
* Entry pName = pointer to struct describing search
|
||
|
* pSymCl = pointer to structure describing path to symbol
|
||
|
* hQual = handle to symbol name
|
||
|
* fProc = TRUE if proc symbol to be searched for
|
||
|
* fProc = FALSE if data to be searched for
|
||
|
|
||
|
* Exit pName updated to reflect search
|
||
|
|
||
|
* Return enum describing search
|
||
|
*/
|
||
|
|
||
|
|
||
|
bool_t
|
||
|
SearchQualName (
|
||
|
psearch_t pName,
|
||
|
psymclass_t pSymCl,
|
||
|
HDEP hQual,
|
||
|
bool_t fProc
|
||
|
)
|
||
|
{
|
||
|
HDEP hTemp;
|
||
|
psearch_t pTemp;
|
||
|
uchar *pQual;
|
||
|
ulong retval;
|
||
|
|
||
|
if ((hTemp = MemAllocate (sizeof (search_t))) == 0) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (FALSE);
|
||
|
}
|
||
|
pTemp = (psearch_t) MemLock (hTemp);
|
||
|
*pTemp = *pName;
|
||
|
pTemp->CXTT = *pCxt;
|
||
|
|
||
|
// set pointer to symbol name
|
||
|
|
||
|
pQual = (uchar *)MemLock (hQual);
|
||
|
pTemp->sstr.lpName = pQual;
|
||
|
pTemp->sstr.cb = (uchar)_tcslen ((char *)pQual);
|
||
|
pTemp->state = SYM_init;
|
||
|
if (fProc == TRUE) {
|
||
|
pTemp->scope = SCP_module | SCP_global;
|
||
|
pTemp->sstr.searchmask |= SSTR_proc;
|
||
|
}
|
||
|
else {
|
||
|
pTemp->scope = SCP_module | SCP_global | SCP_lexical;
|
||
|
|
||
|
// data members may not be overloaded, hence there is
|
||
|
// no need for the type to qualify the name. Furthermore
|
||
|
// there are cases where the symbol type doesn't match
|
||
|
// the member type exactly (e.g. variable length arrays,
|
||
|
// symbol has actual length and member has zero length)
|
||
|
// hence this matching is suppressed for data items [rm]
|
||
|
|
||
|
// pTemp->sstr.searchmask |= SSTR_data;
|
||
|
}
|
||
|
pTemp->initializer = INIT_qual;
|
||
|
pTemp->typeOut = EVAL_TYP (&pSymCl->evalP);
|
||
|
retval = SearchSym (pTemp);
|
||
|
MemUnLock (hQual);
|
||
|
if (retval != HR_found) {
|
||
|
#ifdef NEVER /* CAVIAR #1081 */
|
||
|
if ((retval != HR_end) && (pTemp->FcnBP != 0)) {
|
||
|
// there is another symbol with the same name but a different
|
||
|
// type. Since this is set only when we are binding breakpoints,
|
||
|
// let's go ahead and try it
|
||
|
|
||
|
pTemp->state = SYM_init;
|
||
|
pTemp->scope = SCP_module | SCP_global;
|
||
|
pTemp->sstr.searchmask |= SSTR_proc;
|
||
|
pTemp->typeOut = pTemp->FcnBP;
|
||
|
retval = SearchSym (pTemp);
|
||
|
}
|
||
|
#endif
|
||
|
if (retval != HR_found) {
|
||
|
// the only way we can get here is if the method or data is declared
|
||
|
// in the class but is not defined or is a noninstianted inline method.
|
||
|
// therefore, we return a special error code
|
||
|
|
||
|
if (ST == NULL) {
|
||
|
// this is a hack to get around the case where the expression
|
||
|
// bp {,foo.c, foo.exe}X::f
|
||
|
// and the first function in the module foo is a method.
|
||
|
// SearchSym ended up calling the class search routines
|
||
|
// because the context is implicitly a class so class is
|
||
|
// searched even though it shouldn't be. Any fix for this
|
||
|
// causes problems and we are too close to release to find
|
||
|
// a valid fix. The major result of this fix is that
|
||
|
// some breakpoints will not get reset on entry.
|
||
|
|
||
|
return (FALSE);
|
||
|
}
|
||
|
|
||
|
PushStack (ST);
|
||
|
|
||
|
// if this is a missing static DATA member function then
|
||
|
// best.match won't have anything in it at all... we'll need
|
||
|
// to pick up what we want from typeOut which will have been
|
||
|
// set by a previous non-qualified name search... [rm]
|
||
|
|
||
|
if (pName->best.match == T_NOTYPE) {
|
||
|
SetNodeType (ST, pName->typeOut);
|
||
|
}
|
||
|
else {
|
||
|
SetNodeType (ST, pName->best.match);
|
||
|
}
|
||
|
if (EVAL_IS_FCN(ST)) {
|
||
|
FCN_NOTPRESENT (ST) = TRUE;
|
||
|
}
|
||
|
else {
|
||
|
// indicate missing static data member
|
||
|
EVAL_HSYM (ST) = 0;
|
||
|
pExState->state.fNotPresent = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// pop off the stack entry that a successful search found. Move the
|
||
|
// static data member flag first so that it will not be lost.
|
||
|
|
||
|
EVAL_IS_STMEMBER (ST) = EVAL_IS_STMEMBER (&pSymCl->evalP);
|
||
|
EVAL_ACCESS (ST) = (uchar)(pSymCl->access.access);
|
||
|
pSymCl->evalP = *ST;
|
||
|
MemUnLock (hTemp);
|
||
|
MemFree (hTemp);
|
||
|
return (PopStack ());
|
||
|
}
|
||
|
|
||
|
|
||
|
/** SymAmbToList - add ambiguous symbol to list
|
||
|
|
||
|
* status = SymAmbToList (pName)
|
||
|
|
||
|
* Entry pName = pointer to list describing search
|
||
|
|
||
|
* Exit ambiguous symbol added to list pointed to by pTMList
|
||
|
* pTMLbp
|
||
|
* pName reset to continue breakpoint search
|
||
|
|
||
|
* Returns HR_... describing state
|
||
|
*/
|
||
|
|
||
|
HR_t
|
||
|
SymAmbToList (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
HDEP hSearch;
|
||
|
psearch_t pSearch;
|
||
|
HR_t retval;
|
||
|
HDEP hevalT;
|
||
|
|
||
|
PopStack ();
|
||
|
if (pExState->ambiguous == 0) {
|
||
|
// this is the first breakpoint symbol found.
|
||
|
// indicate the only node in the tree that is
|
||
|
// allowed ambiguity and initialize list of
|
||
|
// symbols for later back patching into duplicated
|
||
|
// expression trees. We save the initial search packet
|
||
|
// so that the first symbol will be set into the breakpoint
|
||
|
// list.
|
||
|
|
||
|
pNameFirst = pName;
|
||
|
pExState->ambiguous = pName->bn;
|
||
|
if ((hSearch = MemAllocate (sizeof (search_t))) == 0) {
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (HR_error);
|
||
|
}
|
||
|
if ((hevalT = MemAllocate (sizeof (eval_t))) == 0) {
|
||
|
MemFree (hSearch);
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (HR_error);
|
||
|
}
|
||
|
pSearch = (psearch_t) MemLock (hSearch);
|
||
|
*pSearch = *pName;
|
||
|
pSearch->pv = (peval_t)MemLock (hevalT);
|
||
|
SHGoToParent (&pName->CXTT, &pSearch->CXTT);
|
||
|
|
||
|
// clear the newly allocated pv
|
||
|
|
||
|
memset ( pSearch->pv, 0, sizeof (eval_t) );
|
||
|
retval = SearchSym (pSearch);
|
||
|
PushStack (pName->pv);
|
||
|
MemUnLock (hSearch);
|
||
|
MemFree (hSearch);
|
||
|
MemUnLock (hevalT);
|
||
|
MemFree (hevalT);
|
||
|
if (retval == HR_end) {
|
||
|
retval = HR_found;
|
||
|
}
|
||
|
return (retval);
|
||
|
}
|
||
|
else if (pExState->ambiguous != pName->bn) {
|
||
|
// there has already been a ambiguous symbol that is
|
||
|
// not at this node in the tree
|
||
|
|
||
|
pExState->err_num = ERR_BPAMBIGUOUS;
|
||
|
return (HR_error);
|
||
|
}
|
||
|
else {
|
||
|
if (CheckDupAmb (pName) == FALSE) {
|
||
|
// the function is not already in the ambiguity list
|
||
|
|
||
|
if (AmbToList (pName) == FALSE) {
|
||
|
return (HR_error);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// reset search to allow more symbols
|
||
|
pName->possibles = 0;
|
||
|
return (SearchSym (pName));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** CheckDupAmb - check for duplicate ambiguity entry
|
||
|
|
||
|
* fSuccess = CheckDupAmb (pName)
|
||
|
|
||
|
* Entry pName = pointer to list describing search
|
||
|
|
||
|
* Exit none
|
||
|
|
||
|
* Returns TRUE if duplicate symbol found
|
||
|
* FALSE if duplicate symbol not found
|
||
|
*/
|
||
|
|
||
|
|
||
|
bool_t
|
||
|
CheckDupAmb (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
psearch_t pN;
|
||
|
ulong i;
|
||
|
bool_t fdup = FALSE;
|
||
|
|
||
|
if ((EVAL_TYP (pNameFirst->pv) == EVAL_TYP (pName->pv)) &&
|
||
|
(memcmp ((void *)&EVAL_SYM (pNameFirst->pv), (void *)&EVAL_SYM (pName->pv),
|
||
|
sizeof (ADDR)) == 0)) {
|
||
|
return (TRUE);
|
||
|
}
|
||
|
for (i = 1; i < iBPatch; i++) {
|
||
|
pN = (psearch_t) MemLock (pTMList[i]);
|
||
|
if (pN->typeOut == EVAL_TYP (pName->pv) &&
|
||
|
(memcmp ((void *)&pN->addr, (void *)&EVAL_SYM (pName->pv),
|
||
|
sizeof (ADDR)) == 0)) {
|
||
|
fdup = TRUE;
|
||
|
}
|
||
|
MemUnLock (pTMList[i]);
|
||
|
if (fdup == TRUE) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return (fdup);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** SymToNode - store symbol information in evaluation node
|
||
|
|
||
|
* fSuccess = SymToNode (hName)
|
||
|
|
||
|
* Entry pName = pointer to search state
|
||
|
|
||
|
* Exit type information and address data stored in value
|
||
|
* if the symbol is a typedef record, then the evaluation
|
||
|
* state will be set to EV_type. Otherwise, it will be set
|
||
|
* to EV_lvalue.
|
||
|
|
||
|
* Returns TRUE if variable was accessible
|
||
|
* FALSE if error
|
||
|
*/
|
||
|
|
||
|
bool_t
|
||
|
SymToNode (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
CV_typ_t typ;
|
||
|
HSYM hSym;
|
||
|
peval_t pv = pName->pv;
|
||
|
PCXT pCXT = &pName->CXTT;
|
||
|
SYMPTR pSym;
|
||
|
ulong cmpThis = 1;
|
||
|
MEMINFO mi;
|
||
|
|
||
|
if ((hSym = pName->hSym) == NULL) {
|
||
|
// this symbol is found as a class member which means it does
|
||
|
// not have a symbol.
|
||
|
|
||
|
DASSERT (pName->typeOut != T_NOTYPE);
|
||
|
return (SetNodeType (pv, pName->typeOut));
|
||
|
}
|
||
|
EVAL_STATE (pv) = EV_lvalue;
|
||
|
EVAL_MOD (pv) = SHHMODFrompCXT (pCXT);
|
||
|
CLEAR_EVAL_FLAGS (pv);
|
||
|
EVAL_SYM_EMI (pv) = pCXT->addr.emi;
|
||
|
switch((pSym = (SYMPTR) MHOmfLock (hSym))->rectyp) {
|
||
|
case S_REGISTER:
|
||
|
EVAL_IS_REG (pv) = TRUE;
|
||
|
EVAL_REG (pv) = ((REGPTR)pSym)->reg;
|
||
|
typ = ((REGPTR)pSym)->typind;
|
||
|
cmpThis = _tcsncmp ( (char *) &((REGPTR)pSym)->name[0],
|
||
|
(char *) &OpName[0], ((REGPTR)pSym)->name[0] + 1);
|
||
|
break;
|
||
|
|
||
|
case S_CONSTANT:
|
||
|
if (!DebLoadConst (pv, (CONSTPTR)pSym, hSym)) {
|
||
|
MHOmfUnLock (hSym);
|
||
|
return (FALSE);
|
||
|
}
|
||
|
EVAL_STATE (pv) = EV_constant;
|
||
|
typ = EVAL_TYP (pv);
|
||
|
break;
|
||
|
|
||
|
|
||
|
case S_UDT:
|
||
|
typ = ((UDTPTR)pSym)->typind;
|
||
|
EVAL_STATE (pv) = EV_type;
|
||
|
break;
|
||
|
|
||
|
case S_BLOCK16:
|
||
|
EVAL_SYM_SEG (pv) = ((BLOCKPTR16)pSym)->seg;
|
||
|
EVAL_SYM_OFF (pv) = ((BLOCKPTR16)pSym)->off;
|
||
|
typ = T_NOTYPE;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
NOTTESTED (FALSE); // not tested
|
||
|
break;
|
||
|
|
||
|
case S_LPROC16:
|
||
|
case S_GPROC16:
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
if ((typ = ((PROCPTR16)pSym)->typind) == T_NOTYPE) {
|
||
|
// this is a hack to allow breakpoints on untyped symbols
|
||
|
typ = T_PFVOID;
|
||
|
EVAL_SYM_OFF (pv) = ((PROCPTR16)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((PROCPTR16)pSym)->seg;
|
||
|
EVAL_PTR (pv) = EVAL_SYM (pv);
|
||
|
EVAL_STATE (pv) = EV_rvalue;
|
||
|
}
|
||
|
else {
|
||
|
EVAL_SYM (pv) = *SHpADDRFrompCXT (pCXT);
|
||
|
EVAL_SYM_SEG (pv) = ((PROCPTR16)pSym)->seg;
|
||
|
EVAL_SYM_OFF (pv) = ((PROCPTR16)pSym)->off;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case S_LABEL16:
|
||
|
EVAL_IS_LABEL (pv) = TRUE;
|
||
|
EVAL_SYM_OFF (pv) = ((LABELPTR16)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((LABELPTR16)pSym)->seg;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
EVAL_PTR (pv) = EVAL_SYM (pv);
|
||
|
EVAL_STATE (pv) = EV_rvalue;
|
||
|
typ = T_PFVOID;
|
||
|
break;
|
||
|
|
||
|
case S_BPREL16:
|
||
|
EVAL_IS_BPREL (pv) = TRUE;
|
||
|
EVAL_SYM_OFF (pv) = ((BPRELPTR16)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = 0;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = FALSE;
|
||
|
typ = ((BPRELPTR16)pSym)->typind;
|
||
|
pExState->state.bprel = TRUE;
|
||
|
cmpThis = _tcsncmp ( (char *) &((BPRELPTR16)pSym)->name[0],
|
||
|
(char *) &OpName[0], ((BPRELPTR16)pSym)->name[0] + 1);
|
||
|
break;
|
||
|
|
||
|
case S_LDATA16:
|
||
|
pExState->state.fLData = TRUE;
|
||
|
EVAL_SYM_OFF (pv) = ((DATAPTR16)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((DATAPTR16)pSym)->seg;
|
||
|
typ = ((DATAPTR16)pSym)->typind;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
break;
|
||
|
|
||
|
case S_GDATA16:
|
||
|
pExState->state.fGData = TRUE;
|
||
|
EVAL_SYM_OFF (pv) = ((DATAPTR16)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((DATAPTR16)pSym)->seg;
|
||
|
typ = ((DATAPTR16)pSym)->typind;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
break;
|
||
|
|
||
|
case S_PUB16:
|
||
|
EVAL_SYM_OFF (pv) = ((DATAPTR16)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((DATAPTR16)pSym)->seg;
|
||
|
EVAL_STATE (pv) = EV_rvalue;
|
||
|
if ((typ = ((DATAPTR16)pSym)->typind) == T_NOTYPE) {
|
||
|
// this is a hack to allow breakpoints on untyped symbold
|
||
|
typ = T_PFVOID;
|
||
|
}
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
EVAL_PTR (pv) = EVAL_SYM (pv);
|
||
|
break;
|
||
|
|
||
|
case S_BLOCK32:
|
||
|
EVAL_SYM_SEG (pv) = ((BLOCKPTR32)pSym)->seg;
|
||
|
EVAL_SYM_OFF (pv) = ((BLOCKPTR32)pSym)->off;
|
||
|
typ = T_NOTYPE;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
ADDRLIN32(EVAL_SYM (pv));
|
||
|
break;
|
||
|
|
||
|
case S_LPROC32:
|
||
|
case S_GPROC32:
|
||
|
ADDRLIN32(EVAL_SYM (pv));
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
if ((typ = ((PROCPTR32)pSym)->typind) == T_NOTYPE) {
|
||
|
// this is a hack to allow breakpoints on untyped symbols
|
||
|
typ = T_32PVOID;
|
||
|
EVAL_SYM_OFF (pv) = ((PROCPTR32)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((PROCPTR32)pSym)->seg;
|
||
|
EVAL_PTR (pv) = EVAL_SYM (pv);
|
||
|
EVAL_STATE (pv) = EV_rvalue;
|
||
|
}
|
||
|
else {
|
||
|
EVAL_SYM (pv) = *SHpADDRFrompCXT (pCXT);
|
||
|
EVAL_SYM_SEG (pv) = ((PROCPTR32)pSym)->seg;
|
||
|
EVAL_SYM_OFF (pv) = ((PROCPTR32)pSym)->off;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case S_LPROCMIPS:
|
||
|
case S_GPROCMIPS:
|
||
|
ADDRLIN32(EVAL_SYM (pv));
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
if ((typ = ((PROCPTRMIPS)pSym)->typind) == T_NOTYPE) {
|
||
|
// this is a hack to allow breakpoints on untyped symbols
|
||
|
typ = T_32PVOID;
|
||
|
EVAL_SYM_OFF (pv) = ((PROCPTRMIPS)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((PROCPTRMIPS)pSym)->seg;
|
||
|
EVAL_PTR (pv) = EVAL_SYM (pv);
|
||
|
EVAL_STATE (pv) = EV_rvalue;
|
||
|
}
|
||
|
else {
|
||
|
EVAL_SYM (pv) = *SHpADDRFrompCXT (pCXT);
|
||
|
EVAL_SYM_SEG (pv) = ((PROCPTRMIPS)pSym)->seg;
|
||
|
EVAL_SYM_OFF (pv) = ((PROCPTRMIPS)pSym)->off;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case S_REGREL32:
|
||
|
EVAL_IS_REGREL (pv) = TRUE;
|
||
|
EVAL_SYM_OFF (pv) = ((LPREGREL32)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = 0;
|
||
|
EVAL_REGREL (pv) = ((LPREGREL32)pSym)->reg;
|
||
|
typ = ((LPREGREL32)pSym)->typind;
|
||
|
ADDRLIN32 (EVAL_SYM (pv));
|
||
|
pExState->state.regrel = TRUE;
|
||
|
cmpThis = _tcsncmp ( (char *) &((LPREGREL32)pSym)->name[0],
|
||
|
(char *) &OpName[0], ((LPREGREL32)pSym)->name[0] + 1);
|
||
|
break;
|
||
|
|
||
|
case S_LABEL32:
|
||
|
EVAL_IS_LABEL (pv) = TRUE;
|
||
|
EVAL_SYM_OFF (pv) = ((LABELPTR32)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((LABELPTR32)pSym)->seg;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
ADDRLIN32(EVAL_SYM (pv));
|
||
|
EVAL_PTR (pv) = EVAL_SYM (pv);
|
||
|
EVAL_STATE (pv) = EV_rvalue;
|
||
|
typ = T_32PVOID;
|
||
|
break;
|
||
|
|
||
|
case S_BPREL32:
|
||
|
EVAL_IS_BPREL (pv) = TRUE;
|
||
|
ADDRLIN32(EVAL_SYM (pv));
|
||
|
EVAL_SYM_OFF (pv) = ((BPRELPTR32)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = 0;
|
||
|
typ = ((BPRELPTR32)pSym)->typind;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = FALSE;
|
||
|
pExState->state.bprel = TRUE;
|
||
|
cmpThis = _tcsncmp ( (char *) &((BPRELPTR32)pSym)->name[0],
|
||
|
(char *) &OpName[0], ((BPRELPTR32)pSym)->name[0] + 1);
|
||
|
break;
|
||
|
|
||
|
case S_LDATA32:
|
||
|
case S_LTHREAD32:
|
||
|
pExState->state.fLData = TRUE;
|
||
|
EVAL_SYM_OFF (pv) = ((DATAPTR32)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((DATAPTR32)pSym)->seg;
|
||
|
typ = ((DATAPTR32)pSym)->typind;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
ADDRLIN32(EVAL_SYM (pv));
|
||
|
break;
|
||
|
|
||
|
case S_GDATA32:
|
||
|
case S_GTHREAD32:
|
||
|
pExState->state.fGData = TRUE;
|
||
|
EVAL_SYM_OFF (pv) = ((DATAPTR32)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((DATAPTR32)pSym)->seg;
|
||
|
typ = ((DATAPTR32)pSym)->typind;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
ADDRLIN32(EVAL_SYM (pv));
|
||
|
break;
|
||
|
|
||
|
case S_PUB32:
|
||
|
#if 0
|
||
|
/*
|
||
|
** This is a hack so we can set breakpoints on publics. This
|
||
|
** allows EEInfoFromTM() to see that it needs to use the AI
|
||
|
** field to get the address to break at. Otherwise it would
|
||
|
** just use the value and not see that it needed to be fixed up
|
||
|
*/
|
||
|
EVAL_IS_LABEL (pv) = TRUE;
|
||
|
EVAL_SYM_OFF (pv) = ((DATAPTR32)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((DATAPTR32)pSym)->seg;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
ADDRLIN32(EVAL_SYM (pv));
|
||
|
EVAL_PTR (pv) = EVAL_SYM (pv);
|
||
|
EVAL_STATE (pv) = EV_rvalue;
|
||
|
typ = T_32PVOID;
|
||
|
break;
|
||
|
#endif
|
||
|
EVAL_SYM_OFF (pv) = ((DATAPTR32)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((DATAPTR32)pSym)->seg;
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
ADDRLIN32(EVAL_SYM (pv));
|
||
|
EVAL_PTR (pv) = EVAL_SYM (pv);
|
||
|
EVAL_STATE (pv) = EV_lvalue;
|
||
|
if ((typ = ((DATAPTR32)pSym)->typind) == T_NOTYPE) {
|
||
|
#if 0
|
||
|
if (FNtsdEvalType) {
|
||
|
FNtsdEvalType = FALSE;
|
||
|
evalstate = EV_rvalue;
|
||
|
typ = T_32PULONG;
|
||
|
} else {
|
||
|
#endif
|
||
|
typ = T_UINT4;
|
||
|
#if 0
|
||
|
evalstate = EV_lvalue;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// this is a hack to allow breakpoints on untyped symbols
|
||
|
|
||
|
mi.addr = EVAL_SYM(pv);
|
||
|
SYGetMemInfo(&mi);
|
||
|
if ((mi.dwState & MEM_COMMIT)
|
||
|
&& (mi.dwProtect & (PAGE_EXECUTE |
|
||
|
PAGE_EXECUTE_READ |
|
||
|
PAGE_EXECUTE_READWRITE |
|
||
|
PAGE_EXECUTE_WRITECOPY))
|
||
|
) {
|
||
|
typ = T_32PUCHAR;
|
||
|
EVAL_STATE (pv) = EV_rvalue;
|
||
|
} else {
|
||
|
#if 0
|
||
|
|
||
|
// this gives windbg the "look & feel" of ntsd/kd
|
||
|
// if the user does a "dd foo" and there are only
|
||
|
// coff publics then the answer will be the same
|
||
|
// as ntsd/kd
|
||
|
|
||
|
EVAL_STATE (pv) = evalstate;
|
||
|
#endif
|
||
|
EVAL_STATE (pv) = EV_lvalue;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case S_REGIA64:
|
||
|
EVAL_IS_REGIA64 (pv) = TRUE;
|
||
|
EVAL_REG (pv) = ((REGPTR)pSym)->reg;
|
||
|
typ = ((REGPTRIA64)pSym)->typind;
|
||
|
cmpThis = _ftcsncmp ( (char FAR *) &((REGPTRIA64)pSym)->name[0],
|
||
|
(char FAR *) &OpName[0], ((REGPTRIA64)pSym)->name[0] + 1);
|
||
|
break;
|
||
|
|
||
|
case S_LPROCIA64:
|
||
|
case S_GPROCIA64:
|
||
|
ADDRLIN32(EVAL_SYM (pv));
|
||
|
ADDR_IS_LI (EVAL_SYM (pv)) = TRUE;
|
||
|
if ((typ = ((PROCPTRIA64)pSym)->typind) == T_NOTYPE) {
|
||
|
// this is a hack to allow breakpoints on untyped symbols
|
||
|
typ = T_32PUCHAR;
|
||
|
EVAL_SYM_OFF (pv) = ((PROCPTRIA64)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = ((PROCPTRIA64)pSym)->seg;
|
||
|
EVAL_PTR (pv) = EVAL_SYM (pv);
|
||
|
EVAL_STATE (pv) = EV_rvalue;
|
||
|
}
|
||
|
else {
|
||
|
EVAL_SYM (pv) = *SHpADDRFrompCXT (pCXT);
|
||
|
EVAL_SYM_SEG (pv) = ((PROCPTRIA64)pSym)->seg;
|
||
|
EVAL_SYM_OFF (pv) = ((PROCPTRIA64)pSym)->off;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case S_REGRELIA64:
|
||
|
EVAL_IS_REGRELIA64 (pv) = TRUE;
|
||
|
EVAL_SYM_OFF (pv) = ((LPREGRELIA64)pSym)->off;
|
||
|
EVAL_SYM_SEG (pv) = 0;
|
||
|
EVAL_REGREL (pv) = ((LPREGRELIA64)pSym)->reg;
|
||
|
typ = ((LPREGRELIA64)pSym)->typind;
|
||
|
ADDRLIN32 (EVAL_SYM (pv));
|
||
|
pExState->state.regrel = TRUE;
|
||
|
cmpThis = _ftcsncmp ( (char FAR *) &((LPREGRELIA64)pSym)->name[0],
|
||
|
(char FAR *) &OpName[0], ((LPREGRELIA64)pSym)->name[0] + 1);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
// these OMF records are no longer supported
|
||
|
MHOmfUnLock (hSym);
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (FALSE);
|
||
|
}
|
||
|
MHOmfUnLock (hSym);
|
||
|
if (SetNodeType (pv, typ) == FALSE) {
|
||
|
return (FALSE);
|
||
|
}
|
||
|
else if (ClassImp != T_NOTYPE) {
|
||
|
if (EVAL_IS_PTR (pv) &&
|
||
|
memcmp (pName->sstr.lpName, &OpName[0] + 1, pName->sstr.cb) == 0) {
|
||
|
PTR_THISADJUST (pv) = ClassThisAdjust;
|
||
|
}
|
||
|
else if (cmpThis == 0) {
|
||
|
PTR_THISADJUST (pv) = ClassThisAdjust;
|
||
|
}
|
||
|
}
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
#define VALIDMPC601 0x01
|
||
|
#define VALIDMPC603 0x02
|
||
|
#define VALIDMPC604 0x04
|
||
|
#define VALIDMPC620 0x08
|
||
|
#define VALIDMPC6xx VALIDMPC601 | VALIDMPC603 | VALIDMPC604 | VALIDMPC620
|
||
|
|
||
|
struct hreg_ppc {
|
||
|
char name[8];
|
||
|
ulong index;
|
||
|
ulong valid;
|
||
|
CV_typ_t type;
|
||
|
} const hreg_list_ppc[] = {
|
||
|
|
||
|
/*
|
||
|
** PowerPC General Registers ( User Level )
|
||
|
*/
|
||
|
{ "\004""GPR0", CV_PPC_GPR0, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\002""R0", CV_PPC_GPR0, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""GPR1", CV_PPC_GPR1, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\002""R1", CV_PPC_GPR1, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\002""SP", CV_PPC_GPR1, VALIDMPC6xx, T_ULONG }, // GPR1 Alias
|
||
|
{ "\004""GPR2", CV_PPC_GPR2, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\002""R2", CV_PPC_GPR2, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""RTOC", CV_PPC_GPR2, VALIDMPC6xx, T_ULONG }, // GPR2 Alias
|
||
|
{ "\004""GPR3", CV_PPC_GPR3, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\002""R3", CV_PPC_GPR3, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""GPR4", CV_PPC_GPR4, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\002""R4", CV_PPC_GPR4, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""GPR5", CV_PPC_GPR5, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\002""R5", CV_PPC_GPR5, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""GPR6", CV_PPC_GPR6, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\002""R6", CV_PPC_GPR6, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""GPR7", CV_PPC_GPR7, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\002""R7", CV_PPC_GPR7, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""GPR8", CV_PPC_GPR8, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\002""R8", CV_PPC_GPR8, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""GPR9", CV_PPC_GPR9, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\002""R9", CV_PPC_GPR9, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR10", CV_PPC_GPR10, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R10", CV_PPC_GPR10, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR11", CV_PPC_GPR11, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R11", CV_PPC_GPR11, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR12", CV_PPC_GPR12, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R12", CV_PPC_GPR12, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR13", CV_PPC_GPR13, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R13", CV_PPC_GPR13, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR14", CV_PPC_GPR14, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R14", CV_PPC_GPR14, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR15", CV_PPC_GPR15, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R15", CV_PPC_GPR15, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR16", CV_PPC_GPR16, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R16", CV_PPC_GPR16, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR17", CV_PPC_GPR17, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R17", CV_PPC_GPR17, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR18", CV_PPC_GPR18, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R18", CV_PPC_GPR18, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR19", CV_PPC_GPR19, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R19", CV_PPC_GPR19, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR20", CV_PPC_GPR20, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R20", CV_PPC_GPR20, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR21", CV_PPC_GPR21, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R21", CV_PPC_GPR21, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR22", CV_PPC_GPR22, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R22", CV_PPC_GPR22, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR23", CV_PPC_GPR23, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R23", CV_PPC_GPR23, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR24", CV_PPC_GPR24, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R24", CV_PPC_GPR24, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR25", CV_PPC_GPR25, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R25", CV_PPC_GPR25, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR26", CV_PPC_GPR26, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R26", CV_PPC_GPR26, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR27", CV_PPC_GPR27, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R27", CV_PPC_GPR27, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR28", CV_PPC_GPR28, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R28", CV_PPC_GPR28, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR29", CV_PPC_GPR29, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R29", CV_PPC_GPR29, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR30", CV_PPC_GPR30, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R30", CV_PPC_GPR30, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""GPR31", CV_PPC_GPR31, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""R31", CV_PPC_GPR31, VALIDMPC6xx, T_ULONG },
|
||
|
|
||
|
/*
|
||
|
** PowerPC Condition Register ( User Level )
|
||
|
*/
|
||
|
{ "\002""CR", CV_PPC_CR, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""CR0", CV_PPC_CR0, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""CR1", CV_PPC_CR1, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""CR2", CV_PPC_CR2, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""CR3", CV_PPC_CR3, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""CR4", CV_PPC_CR4, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""CR5", CV_PPC_CR5, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""CR6", CV_PPC_CR6, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""CR7", CV_PPC_CR7, VALIDMPC6xx, T_ULONG },
|
||
|
|
||
|
/*
|
||
|
** PowerPC Floating Point Registers ( User Level )
|
||
|
|
||
|
** The floating point registers aren't really 80 bytes however the
|
||
|
** shell expects that they are so we say they are and thusly the em
|
||
|
** turns the 64bit doubles into 80bit long doubles before returning them
|
||
|
*/
|
||
|
{ "\004""FPR0", CV_PPC_FPR0, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\003""FP0", CV_PPC_FPR0, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FPR1", CV_PPC_FPR1, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\003""FP1", CV_PPC_FPR1, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FPR2", CV_PPC_FPR2, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\003""FP2", CV_PPC_FPR2, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FPR3", CV_PPC_FPR3, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\003""FP3", CV_PPC_FPR3, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FPR4", CV_PPC_FPR4, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\003""FP4", CV_PPC_FPR4, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FPR5", CV_PPC_FPR5, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\003""FP5", CV_PPC_FPR5, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FPR6", CV_PPC_FPR6, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\003""FP6", CV_PPC_FPR6, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FPR7", CV_PPC_FPR7, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\003""FP7", CV_PPC_FPR7, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FPR8", CV_PPC_FPR8, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\003""FP8", CV_PPC_FPR8, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FPR9", CV_PPC_FPR9, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\003""FP9", CV_PPC_FPR9, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR10", CV_PPC_FPR10, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP10", CV_PPC_FPR10, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR11", CV_PPC_FPR11, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP11", CV_PPC_FPR11, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR12", CV_PPC_FPR12, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP12", CV_PPC_FPR12, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR13", CV_PPC_FPR13, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP13", CV_PPC_FPR13, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR14", CV_PPC_FPR14, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP14", CV_PPC_FPR14, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR15", CV_PPC_FPR15, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP15", CV_PPC_FPR15, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR16", CV_PPC_FPR16, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP16", CV_PPC_FPR16, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR17", CV_PPC_FPR17, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP17", CV_PPC_FPR17, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR18", CV_PPC_FPR18, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP18", CV_PPC_FPR18, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR19", CV_PPC_FPR19, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP19", CV_PPC_FPR19, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR20", CV_PPC_FPR20, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP20", CV_PPC_FPR20, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR21", CV_PPC_FPR21, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP21", CV_PPC_FPR21, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR22", CV_PPC_FPR22, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP22", CV_PPC_FPR22, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR23", CV_PPC_FPR23, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP23", CV_PPC_FPR23, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR24", CV_PPC_FPR24, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP24", CV_PPC_FPR24, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR25", CV_PPC_FPR25, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP25", CV_PPC_FPR25, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR26", CV_PPC_FPR26, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP26", CV_PPC_FPR26, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR27", CV_PPC_FPR27, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP27", CV_PPC_FPR27, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR28", CV_PPC_FPR28, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP28", CV_PPC_FPR28, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR29", CV_PPC_FPR29, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP29", CV_PPC_FPR29, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR30", CV_PPC_FPR30, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP30", CV_PPC_FPR30, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\005""FPR31", CV_PPC_FPR31, VALIDMPC6xx, T_REAL80 },
|
||
|
{ "\004""FP31", CV_PPC_FPR31, VALIDMPC6xx, T_REAL80 },
|
||
|
|
||
|
/*
|
||
|
** PowerPC Floating Point Status and Control Register ( User Level )
|
||
|
*/
|
||
|
{ "\005""FPSCR", CV_PPC_FPSCR, VALIDMPC6xx, T_ULONG },
|
||
|
|
||
|
/*
|
||
|
** PowerPC Machine State Register ( Supervisor Level )
|
||
|
*/
|
||
|
{ "\003""MSR", CV_PPC_MSR, VALIDMPC6xx, T_ULONG },
|
||
|
|
||
|
/*
|
||
|
** PowerPC Segment Registers ( Supervisor Level )
|
||
|
*/
|
||
|
{ "\003""SR0", CV_PPC_SR0, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR1", CV_PPC_SR1, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR2", CV_PPC_SR2, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR3", CV_PPC_SR3, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR4", CV_PPC_SR4, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR5", CV_PPC_SR5, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR6", CV_PPC_SR6, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR7", CV_PPC_SR7, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR8", CV_PPC_SR8, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR9", CV_PPC_SR9, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR10", CV_PPC_SR10, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR11", CV_PPC_SR11, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR12", CV_PPC_SR12, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR13", CV_PPC_SR13, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR14", CV_PPC_SR14, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""SR15", CV_PPC_SR15, VALIDMPC6xx, T_ULONG },
|
||
|
|
||
|
/*
|
||
|
** For all of the special purpose registers add 100 to the SPR# that the
|
||
|
** Motorola/IBM documentation gives with the exception of any imaginary
|
||
|
** registers.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
** PowerPC Special Purpose Registers ( User Level )
|
||
|
*/
|
||
|
{ "\002""PC", CV_PPC_PC, VALIDMPC6xx, T_ULONG }, // PC (imaginary register)
|
||
|
|
||
|
{ "\002""MQ", CV_PPC_MQ, VALIDMPC601, T_ULONG }, // MPC601
|
||
|
{ "\003""XER", CV_PPC_XER, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""RTCU", CV_PPC_RTCU, VALIDMPC601, T_ULONG }, // MPC601
|
||
|
{ "\004""RTCL", CV_PPC_RTCL, VALIDMPC601, T_ULONG }, // MPC601
|
||
|
{ "\002""LR", CV_PPC_LR, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""CTR", CV_PPC_CTR, VALIDMPC6xx, T_ULONG },
|
||
|
|
||
|
/*
|
||
|
** PowerPC Special Purpose Registers ( Supervisor Level )
|
||
|
*/
|
||
|
{ "\005""DSISR", CV_PPC_DSISR, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""DAR", CV_PPC_DAR, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""DEC", CV_PPC_DEC, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""SDR1", CV_PPC_SDR1, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""SRR0", CV_PPC_SRR0, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\004""SRR1", CV_PPC_SRR1, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""SPRG0", CV_PPC_SPRG0, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""SPRG1", CV_PPC_SPRG1, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""SPRG2", CV_PPC_SPRG2, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""SPRG3", CV_PPC_SPRG3, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""ASR", CV_PPC_ASR, VALIDMPC6xx, T_ULONG }, // 64-bit implementations only
|
||
|
{ "\003""EAR", CV_PPC_EAR, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\003""PVR", CV_PPC_PVR, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""BAT0U", CV_PPC_BAT0U, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""BAT0L", CV_PPC_BAT0L, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""BAT1U", CV_PPC_BAT1U, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""BAT1L", CV_PPC_BAT1L, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""BAT2U", CV_PPC_BAT2U, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""BAT2L", CV_PPC_BAT2L, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""BAT3U", CV_PPC_BAT3U, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\005""BAT3L", CV_PPC_BAT3L, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\006""DBAT0U", CV_PPC_DBAT0U, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\006""DBAT0L", CV_PPC_DBAT0L, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\006""DBAT1U", CV_PPC_DBAT1U, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\006""DBAT1L", CV_PPC_DBAT1L, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\006""DBAT2U", CV_PPC_DBAT2U, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\006""DBAT2L", CV_PPC_DBAT2L, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\006""DBAT3U", CV_PPC_DBAT3U, VALIDMPC6xx, T_ULONG },
|
||
|
{ "\006""DBAT3L", CV_PPC_DBAT3L, VALIDMPC6xx, T_ULONG },
|
||
|
|
||
|
/*
|
||
|
** PowerPC Special Purpose Registers Implementation Dependent ( Supervisor Level )
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
** Doesn't appear that IBM/Motorola has finished defining these.
|
||
|
*/
|
||
|
|
||
|
{ "\004""PMR0", CV_PPC_PMR0, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\004""PMR1", CV_PPC_PMR1, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\004""PMR2", CV_PPC_PMR2, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\004""PMR3", CV_PPC_PMR3, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\004""PMR4", CV_PPC_PMR4, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\004""PMR5", CV_PPC_PMR5, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\004""PMR6", CV_PPC_PMR6, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\004""PMR7", CV_PPC_PMR7, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\004""PMR8", CV_PPC_PMR8, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\004""PMR9", CV_PPC_PMR9, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\005""PMR10", CV_PPC_PMR10, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\005""PMR11", CV_PPC_PMR11, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\005""PMR12", CV_PPC_PMR12, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\005""PMR13", CV_PPC_PMR13, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\005""PMR14", CV_PPC_PMR14, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
{ "\005""PMR15", CV_PPC_PMR15, VALIDMPC620, T_ULONG }, // MPC620
|
||
|
|
||
|
{ "\005""DMISS", CV_PPC_DMISS, VALIDMPC603, T_ULONG }, // MPC603
|
||
|
{ "\004""DCMP", CV_PPC_DCMP, VALIDMPC603, T_ULONG }, // MPC603
|
||
|
{ "\005""HASH1", CV_PPC_HASH1, VALIDMPC603, T_ULONG }, // MPC603
|
||
|
{ "\005""HASH2", CV_PPC_HASH2, VALIDMPC603, T_ULONG }, // MPC603
|
||
|
{ "\005""IMISS", CV_PPC_IMISS, VALIDMPC603, T_ULONG }, // MPC603
|
||
|
{ "\004""ICMP", CV_PPC_ICMP, VALIDMPC603, T_ULONG }, // MPC603
|
||
|
{ "\003""RPA", CV_PPC_RPA, VALIDMPC603, T_ULONG }, // MPC603
|
||
|
|
||
|
{ "\004""HID0", CV_PPC_HID0, VALIDMPC601 | VALIDMPC603 | VALIDMPC620, T_ULONG }, // MPC601, MPC603, MPC620
|
||
|
{ "\004""HID1", CV_PPC_HID1, VALIDMPC601, T_ULONG }, // MPC601
|
||
|
{ "\004""HID2", CV_PPC_HID2, VALIDMPC601 | VALIDMPC603 | VALIDMPC620, T_ULONG }, // MPC601, MPC603, MPC620 ( IABR )
|
||
|
{ "\004""HID3", CV_PPC_HID3, VALIDMPC6xx, T_ULONG }, // Not Defined
|
||
|
{ "\004""HID4", CV_PPC_HID4, VALIDMPC6xx, T_ULONG }, // Not Defined
|
||
|
{ "\004""HID5", CV_PPC_HID5, VALIDMPC601 | VALIDMPC604 | VALIDMPC620, T_ULONG }, // MPC601, MPC604, MPC620 ( DABR )
|
||
|
{ "\004""HID6", CV_PPC_HID6, VALIDMPC6xx, T_ULONG }, // Not Defined
|
||
|
{ "\004""HID7", CV_PPC_HID7, VALIDMPC6xx, T_ULONG }, // Not Defined
|
||
|
{ "\004""HID8", CV_PPC_HID8, VALIDMPC620, T_ULONG }, // MPC620 ( BUSCSR )
|
||
|
{ "\004""HID9", CV_PPC_HID9, VALIDMPC620, T_ULONG }, // MPC620 ( L2CSR )
|
||
|
{ "\005""HID10", CV_PPC_HID10, VALIDMPC6xx, T_ULONG }, // Not Defined
|
||
|
{ "\005""HID11", CV_PPC_HID11, VALIDMPC6xx, T_ULONG }, // Not Defined
|
||
|
{ "\005""HID12", CV_PPC_HID12, VALIDMPC6xx, T_ULONG }, // Not Defined
|
||
|
{ "\005""HID13", CV_PPC_HID13, VALIDMPC604, T_ULONG }, // MPC604 ( HCR )
|
||
|
{ "\005""HID14", CV_PPC_HID14, VALIDMPC6xx, T_ULONG }, // Not Defined
|
||
|
{ "\005""HID15", CV_PPC_HID15, VALIDMPC601 | VALIDMPC604 | VALIDMPC620, T_ULONG } // MPC601, MPC604, MPC620 ( PIR )
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
#define VALID68851 0x40
|
||
|
#define VALID68882 0x80
|
||
|
|
||
|
#define VALID68000 0x01
|
||
|
#define VALID68010 0x02 | VALID68000
|
||
|
#define VALID68020 0x04 | VALID68010
|
||
|
#define VALID68030 0x08 | VALID68020 | VALID68851
|
||
|
#define VALID68040 0x10 | VALID68030
|
||
|
|
||
|
struct hreg_68k {
|
||
|
char name[7];
|
||
|
ulong index;
|
||
|
ulong valid;
|
||
|
CV_typ_t type;
|
||
|
} const hreg_list_68k[] = {
|
||
|
{"\x002""D0", CV_R68_D0, VALID68000, T_ULONG},
|
||
|
{"\x002""D1", CV_R68_D1, VALID68000, T_ULONG},
|
||
|
{"\x002""D2", CV_R68_D2, VALID68000, T_ULONG},
|
||
|
{"\x002""D3", CV_R68_D3, VALID68000, T_ULONG},
|
||
|
{"\x002""D4", CV_R68_D4, VALID68000, T_ULONG},
|
||
|
{"\x002""D5", CV_R68_D5, VALID68000, T_ULONG},
|
||
|
{"\x002""D6", CV_R68_D6, VALID68000, T_ULONG},
|
||
|
{"\x002""D7", CV_R68_D7, VALID68000, T_ULONG},
|
||
|
{"\x002""A0", CV_R68_A0, VALID68000, T_ULONG},
|
||
|
{"\x002""A1", CV_R68_A1, VALID68000, T_ULONG},
|
||
|
{"\x002""A2", CV_R68_A2, VALID68000, T_ULONG},
|
||
|
{"\x002""A3", CV_R68_A3, VALID68000, T_ULONG},
|
||
|
{"\x002""A4", CV_R68_A4, VALID68000, T_ULONG},
|
||
|
{"\x002""A5", CV_R68_A5, VALID68000, T_ULONG},
|
||
|
{"\x002""A6", CV_R68_A6, VALID68000, T_ULONG},
|
||
|
{"\x002""A7", CV_R68_A7, VALID68000, T_ULONG},
|
||
|
{"\x003""CCR", CV_R68_CCR, VALID68000, T_UCHAR},
|
||
|
{"\x002""SR", CV_R68_SR, VALID68000, T_USHORT},
|
||
|
#if 0
|
||
|
{"\x003""USP", CV_R68_USP, VALID68000, T_ULONG},
|
||
|
{"\x003""MSP", CV_R68_MSP, VALID68000, T_ULONG},
|
||
|
#endif
|
||
|
{"\x002""PC", CV_R68_PC, VALID68000, T_ULONG},
|
||
|
|
||
|
#if 0
|
||
|
{"\x003""SFC", CV_R68_SFC, VALID68010, T_USHORT},
|
||
|
{"\x003""DFC", CV_R68_DFC, VALID68010, T_USHORT},
|
||
|
{"\x003""VBR", CV_R68_VBR, VALID68010, T_USHORT},
|
||
|
|
||
|
{"\x004""CACR", CV_R68_CACR, VALID68020, T_ULONG},
|
||
|
{"\x004""CAAR", CV_R68_CAAR, VALID68020, T_ULONG},
|
||
|
{"\x003""ISP", CV_R68_ISP, VALID68020, T_ULONG},
|
||
|
|
||
|
{"\x003""PSR", CV_R68_PSR, VALID68851, T_USHORT},
|
||
|
{"\x004""PCSR", CV_R68_PCSR, VALID68851, T_USHORT},
|
||
|
{"\x003""VAL", CV_R68_VAL, VALID68851, T_USHORT},
|
||
|
{"\x003""CRP", CV_R68_CRP, VALID68851, T_UQUAD},
|
||
|
{"\x003""SRP", CV_R68_SRP, VALID68851, T_UQUAD},
|
||
|
{"\x003""DRP", CV_R68_DRP, VALID68851, T_UQUAD},
|
||
|
{"\x002""TC", CV_R68_TC, VALID68851, T_ULONG},
|
||
|
{"\x002""AC", CV_R68_AC, VALID68851, T_USHORT},
|
||
|
{"\x003""SCC", CV_R68_SCC, VALID68851, T_USHORT},
|
||
|
{"\x003""CAL", CV_R68_CAL, VALID68851, T_USHORT},
|
||
|
{"\x004""BAD0", CV_R68_BAD0, VALID68851, T_USHORT},
|
||
|
{"\x004""BAD1", CV_R68_BAD1, VALID68851, T_USHORT},
|
||
|
{"\x004""BAD2", CV_R68_BAD2, VALID68851, T_USHORT},
|
||
|
{"\x004""BAD3", CV_R68_BAD3, VALID68851, T_USHORT},
|
||
|
{"\x004""BAD4", CV_R68_BAD4, VALID68851, T_USHORT},
|
||
|
{"\x004""BAD5", CV_R68_BAD5, VALID68851, T_USHORT},
|
||
|
{"\x004""BAD6", CV_R68_BAD6, VALID68851, T_USHORT},
|
||
|
{"\x004""BAD7", CV_R68_BAD7, VALID68851, T_USHORT},
|
||
|
{"\x004""BAC0", CV_R68_BAC0, VALID68851, T_USHORT},
|
||
|
{"\x004""BAC1", CV_R68_BAC1, VALID68851, T_USHORT},
|
||
|
{"\x004""BAC2", CV_R68_BAC2, VALID68851, T_USHORT},
|
||
|
{"\x004""BAC3", CV_R68_BAC3, VALID68851, T_USHORT},
|
||
|
{"\x004""BAC4", CV_R68_BAC4, VALID68851, T_USHORT},
|
||
|
{"\x004""BAC5", CV_R68_BAC5, VALID68851, T_USHORT},
|
||
|
{"\x004""BAC6", CV_R68_BAC6, VALID68851, T_USHORT},
|
||
|
{"\x004""BAC7", CV_R68_BAC7, VALID68851, T_USHORT},
|
||
|
|
||
|
{"\x003""TT0", CV_R68_TT0, VALID68030, T_ULONG},
|
||
|
{"\x003""TT1", CV_R68_TT1, VALID68030, T_ULONG},
|
||
|
#endif
|
||
|
|
||
|
{"\x004""FPCR", CV_R68_FPCR, VALID68882, T_ULONG},
|
||
|
{"\x004""FPSR", CV_R68_FPSR, VALID68882, T_ULONG},
|
||
|
{"\x005""FPIAR", CV_R68_FPIAR, VALID68882, T_ULONG},
|
||
|
{"\x003""FP0", CV_R68_FP0, VALID68882, T_REAL80},
|
||
|
{"\x003""FP1", CV_R68_FP1, VALID68882, T_REAL80},
|
||
|
{"\x003""FP2", CV_R68_FP2, VALID68882, T_REAL80},
|
||
|
{"\x003""FP3", CV_R68_FP3, VALID68882, T_REAL80},
|
||
|
{"\x003""FP4", CV_R68_FP4, VALID68882, T_REAL80},
|
||
|
{"\x003""FP5", CV_R68_FP5, VALID68882, T_REAL80},
|
||
|
{"\x003""FP6", CV_R68_FP6, VALID68882, T_REAL80},
|
||
|
{"\x003""FP7", CV_R68_FP7, VALID68882, T_REAL80},
|
||
|
};
|
||
|
|
||
|
|
||
|
#define VALIDx86 0x01
|
||
|
#define VALID386 0x02
|
||
|
#define REGHI 0x04
|
||
|
#define REGLO 0x08
|
||
|
#define VALIDx87 0x10
|
||
|
|
||
|
struct hreg_x86 {
|
||
|
char name[5];
|
||
|
int index;
|
||
|
ulong valid;
|
||
|
CV_typ_t type;
|
||
|
} const hreg_list_x86[] = {
|
||
|
{"\x002""AX", CV_REG_AX, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""BX", CV_REG_BX, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""CX", CV_REG_CX, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""DX", CV_REG_DX, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""SP", CV_REG_SP, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""BP", CV_REG_BP, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""SI", CV_REG_SI, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""DI", CV_REG_DI, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""DS", CV_REG_DS, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""ES", CV_REG_ES, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""SS", CV_REG_SS, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""CS", CV_REG_CS, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""IP", CV_REG_IP, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x002""FL", CV_REG_FLAGS, VALIDx86 | VALID386, T_USHORT},
|
||
|
{"\x003""EFL", CV_REG_EFLAGS, VALID386, T_ULONG},
|
||
|
{"\x003""EAX", CV_REG_EAX, VALID386, T_ULONG},
|
||
|
{"\x003""EBX", CV_REG_EBX, VALID386, T_ULONG},
|
||
|
{"\x003""ECX", CV_REG_ECX, VALID386, T_ULONG},
|
||
|
{"\x003""EDX", CV_REG_EDX, VALID386, T_ULONG},
|
||
|
{"\x003""ESP", CV_REG_ESP, VALID386, T_ULONG},
|
||
|
{"\x003""EBP", CV_REG_EBP, VALID386, T_ULONG},
|
||
|
{"\x003""ESI", CV_REG_ESI, VALID386, T_ULONG},
|
||
|
{"\x003""EDI", CV_REG_EDI, VALID386, T_ULONG},
|
||
|
{"\x003""EIP", CV_REG_EIP, VALID386, T_ULONG},
|
||
|
{"\x002""PQ", CV_REG_QUOTE, VALIDx86, T_USHORT},
|
||
|
{"\x002""TL", CV_REG_TEMP, VALIDx86, T_USHORT},
|
||
|
{"\x002""TH", CV_REG_TEMPH, VALIDx86, T_USHORT},
|
||
|
{"\x002""FS", CV_REG_FS, VALID386, T_USHORT},
|
||
|
{"\x002""GS", CV_REG_GS, VALID386, T_USHORT},
|
||
|
{"\x002""AH", CV_REG_AH, VALIDx86 | VALID386 | REGHI, T_UCHAR},
|
||
|
{"\x002""BH", CV_REG_BH, VALIDx86 | VALID386 | REGHI, T_UCHAR},
|
||
|
{"\x002""CH", CV_REG_CH, VALIDx86 | VALID386 | REGHI, T_UCHAR},
|
||
|
{"\x002""DH", CV_REG_DH, VALIDx86 | VALID386 | REGHI, T_UCHAR},
|
||
|
{"\x002""AL", CV_REG_AL, VALIDx86 | VALID386 | REGLO, T_UCHAR},
|
||
|
{"\x002""BL", CV_REG_BL, VALIDx86 | VALID386 | REGLO, T_UCHAR},
|
||
|
{"\x002""CL", CV_REG_CL, VALIDx86 | VALID386 | REGLO, T_UCHAR},
|
||
|
{"\x002""DL", CV_REG_DL, VALIDx86 | VALID386 | REGLO, T_UCHAR},
|
||
|
{"\x002""st", CV_REG_ST0, VALIDx86 | VALID386 | VALIDx87, T_REAL80},
|
||
|
{"\x003""st0", CV_REG_ST0, VALIDx86 | VALID386 | VALIDx87, T_REAL80},
|
||
|
{"\x003""st1", CV_REG_ST1, VALIDx86 | VALID386 | VALIDx87, T_REAL80},
|
||
|
{"\x003""st2", CV_REG_ST2, VALIDx86 | VALID386 | VALIDx87, T_REAL80},
|
||
|
{"\x003""st3", CV_REG_ST3, VALIDx86 | VALID386 | VALIDx87, T_REAL80},
|
||
|
{"\x003""st4", CV_REG_ST4, VALIDx86 | VALID386 | VALIDx87, T_REAL80},
|
||
|
{"\x003""st5", CV_REG_ST5, VALIDx86 | VALID386 | VALIDx87, T_REAL80},
|
||
|
{"\x003""st6", CV_REG_ST6, VALIDx86 | VALID386 | VALIDx87, T_REAL80},
|
||
|
{"\x003""st7", CV_REG_ST7, VALIDx86 | VALID386 | VALIDx87, T_REAL80},
|
||
|
{"\x003""MM0", CV_REG_MM0, VALIDx86 , T_UQUAD},
|
||
|
{"\x003""MM1", CV_REG_MM1, VALIDx86 , T_UQUAD},
|
||
|
{"\x003""MM2", CV_REG_MM2, VALIDx86 , T_UQUAD},
|
||
|
{"\x003""MM3", CV_REG_MM3, VALIDx86 , T_UQUAD},
|
||
|
{"\x003""MM4", CV_REG_MM4, VALIDx86 , T_UQUAD},
|
||
|
{"\x003""MM5", CV_REG_MM5, VALIDx86 , T_UQUAD},
|
||
|
{"\x003""MM6", CV_REG_MM6, VALIDx86 , T_UQUAD},
|
||
|
{"\x003""MM7", CV_REG_MM7, VALIDx86 , T_UQUAD},
|
||
|
// {"\x003""TEB", CV_REG_TEB, VALIDx86, T_ULONG},
|
||
|
// {"\x003""ERR", CV_REG_ERR, VALIDx86, T_ULONG},
|
||
|
};
|
||
|
|
||
|
struct hreg_mip {
|
||
|
char name[5];
|
||
|
int index;
|
||
|
CV_typ_t type;
|
||
|
} const hreg_list_mip[] = {
|
||
|
{"\004""ZERO", CV_M4_IntZERO, T_ULONG},
|
||
|
{"\002""AT", CV_M4_IntAT, T_ULONG},
|
||
|
{"\002""V0", CV_M4_IntV0, T_ULONG},
|
||
|
{"\002""V1", CV_M4_IntV1, T_ULONG},
|
||
|
{"\002""A0", CV_M4_IntA0, T_ULONG},
|
||
|
{"\002""A1", CV_M4_IntA1, T_ULONG},
|
||
|
{"\002""A2", CV_M4_IntA2, T_ULONG},
|
||
|
{"\002""A3", CV_M4_IntA3, T_ULONG},
|
||
|
{"\002""T0", CV_M4_IntT0, T_ULONG},
|
||
|
{"\002""T1", CV_M4_IntT1, T_ULONG},
|
||
|
{"\002""T2", CV_M4_IntT2, T_ULONG},
|
||
|
{"\002""T3", CV_M4_IntT3, T_ULONG},
|
||
|
{"\002""T4", CV_M4_IntT4, T_ULONG},
|
||
|
{"\002""T5", CV_M4_IntT5, T_ULONG},
|
||
|
{"\002""T6", CV_M4_IntT6, T_ULONG},
|
||
|
{"\002""T7", CV_M4_IntT7, T_ULONG},
|
||
|
{"\002""T8", CV_M4_IntT8, T_ULONG},
|
||
|
{"\002""T9", CV_M4_IntT9, T_ULONG},
|
||
|
{"\002""S0", CV_M4_IntS0, T_ULONG},
|
||
|
{"\002""S1", CV_M4_IntS1, T_ULONG},
|
||
|
{"\002""S2", CV_M4_IntS2, T_ULONG},
|
||
|
{"\002""S3", CV_M4_IntS3, T_ULONG},
|
||
|
{"\002""S4", CV_M4_IntS4, T_ULONG},
|
||
|
{"\002""S5", CV_M4_IntS5, T_ULONG},
|
||
|
{"\002""S6", CV_M4_IntS6, T_ULONG},
|
||
|
{"\002""S7", CV_M4_IntS7, T_ULONG},
|
||
|
{"\002""S8", CV_M4_IntS8, T_ULONG},
|
||
|
{"\002""K0", CV_M4_IntKT0, T_ULONG},
|
||
|
{"\002""K1", CV_M4_IntKT1, T_ULONG},
|
||
|
{"\002""GP", CV_M4_IntGP, T_ULONG},
|
||
|
{"\002""SP", CV_M4_IntSP, T_ULONG},
|
||
|
{"\002""RA", CV_M4_IntRA, T_ULONG},
|
||
|
{"\003""FIR", CV_M4_Fir, T_ULONG},
|
||
|
{"\002""PC", CV_M4_Fir, T_ULONG},
|
||
|
{"\003""PSR", CV_M4_Psr, T_ULONG},
|
||
|
{"\003""FSR", CV_M4_FltFsr, T_ULONG},
|
||
|
{"\002""HI", CV_M4_IntHI, T_ULONG},
|
||
|
{"\002""LO", CV_M4_IntLO, T_ULONG},
|
||
|
{"\003""FR0", CV_M4_FltF0, T_REAL32},
|
||
|
{"\003""FR1", CV_M4_FltF1, T_REAL32},
|
||
|
{"\003""FR2", CV_M4_FltF2, T_REAL32},
|
||
|
{"\003""FR3", CV_M4_FltF3, T_REAL32},
|
||
|
{"\003""FR4", CV_M4_FltF4, T_REAL32},
|
||
|
{"\003""FR5", CV_M4_FltF5, T_REAL32},
|
||
|
{"\003""FR6", CV_M4_FltF6, T_REAL32},
|
||
|
{"\003""FR7", CV_M4_FltF7, T_REAL32},
|
||
|
{"\003""FR8", CV_M4_FltF8, T_REAL32},
|
||
|
{"\003""FR9", CV_M4_FltF9, T_REAL32},
|
||
|
{"\004""FR10", CV_M4_FltF10, T_REAL32},
|
||
|
{"\004""FR11", CV_M4_FltF11, T_REAL32},
|
||
|
{"\004""FR12", CV_M4_FltF12, T_REAL32},
|
||
|
{"\004""FR13", CV_M4_FltF13, T_REAL32},
|
||
|
{"\004""FR14", CV_M4_FltF14, T_REAL32},
|
||
|
{"\004""FR15", CV_M4_FltF15, T_REAL32},
|
||
|
{"\004""FR16", CV_M4_FltF16, T_REAL32},
|
||
|
{"\004""FR17", CV_M4_FltF17, T_REAL32},
|
||
|
{"\004""FR18", CV_M4_FltF18, T_REAL32},
|
||
|
{"\004""FR19", CV_M4_FltF19, T_REAL32},
|
||
|
{"\004""FR20", CV_M4_FltF20, T_REAL32},
|
||
|
{"\004""FR21", CV_M4_FltF21, T_REAL32},
|
||
|
{"\004""FR22", CV_M4_FltF22, T_REAL32},
|
||
|
{"\004""FR23", CV_M4_FltF23, T_REAL32},
|
||
|
{"\004""FR24", CV_M4_FltF24, T_REAL32},
|
||
|
{"\004""FR25", CV_M4_FltF25, T_REAL32},
|
||
|
{"\004""FR26", CV_M4_FltF26, T_REAL32},
|
||
|
{"\004""FR27", CV_M4_FltF27, T_REAL32},
|
||
|
{"\004""FR28", CV_M4_FltF28, T_REAL32},
|
||
|
{"\004""FR29", CV_M4_FltF29, T_REAL32},
|
||
|
{"\004""FR30", CV_M4_FltF30, T_REAL32},
|
||
|
{"\004""FR31", CV_M4_FltF31, T_REAL32},
|
||
|
{"\003""FP0", CV_M4_FltF1 << 8 | CV_M4_FltF0, T_REAL64},
|
||
|
{"\003""FP2", CV_M4_FltF3 << 8 | CV_M4_FltF2, T_REAL64},
|
||
|
{"\003""FP4", CV_M4_FltF5 << 8 | CV_M4_FltF4, T_REAL64},
|
||
|
{"\003""FP6", CV_M4_FltF7 << 8 | CV_M4_FltF6, T_REAL64},
|
||
|
{"\003""FP8", CV_M4_FltF9 << 8 | CV_M4_FltF8, T_REAL64},
|
||
|
{"\004""FP10", CV_M4_FltF11 << 8 | CV_M4_FltF10, T_REAL64},
|
||
|
{"\004""FP12", CV_M4_FltF13 << 8 | CV_M4_FltF12, T_REAL64},
|
||
|
{"\004""FP14", CV_M4_FltF15 << 8 | CV_M4_FltF14, T_REAL64},
|
||
|
{"\004""FP16", CV_M4_FltF17 << 8 | CV_M4_FltF16, T_REAL64},
|
||
|
{"\004""FP18", CV_M4_FltF19 << 8 | CV_M4_FltF18, T_REAL64},
|
||
|
{"\004""FP20", CV_M4_FltF21 << 8 | CV_M4_FltF20, T_REAL64},
|
||
|
{"\004""FP22", CV_M4_FltF23 << 8 | CV_M4_FltF22, T_REAL64},
|
||
|
{"\004""FP24", CV_M4_FltF25 << 8 | CV_M4_FltF24, T_REAL64},
|
||
|
{"\004""FP26", CV_M4_FltF27 << 8 | CV_M4_FltF26, T_REAL64},
|
||
|
{"\004""FP28", CV_M4_FltF29 << 8 | CV_M4_FltF28, T_REAL64},
|
||
|
{"\004""FP30", CV_M4_FltF31 << 8 | CV_M4_FltF30, T_REAL64},
|
||
|
};
|
||
|
struct hreg_axp {
|
||
|
char name[5];
|
||
|
int index;
|
||
|
CV_typ_t type;
|
||
|
} hreg_list_axp[] = {
|
||
|
{"\004""ZERO", CV_ALPHA_IntZERO, T_UQUAD},
|
||
|
{"\002""AT", CV_ALPHA_IntAT, T_UQUAD},
|
||
|
{"\002""V0", CV_ALPHA_IntV0, T_UQUAD},
|
||
|
{"\002""A0", CV_ALPHA_IntA0, T_UQUAD},
|
||
|
{"\002""A1", CV_ALPHA_IntA1, T_UQUAD},
|
||
|
{"\002""A2", CV_ALPHA_IntA2, T_UQUAD},
|
||
|
{"\002""A3", CV_ALPHA_IntA3, T_UQUAD},
|
||
|
{"\002""A4", CV_ALPHA_IntA4, T_UQUAD},
|
||
|
{"\002""A5", CV_ALPHA_IntA5, T_UQUAD},
|
||
|
{"\002""T0", CV_ALPHA_IntT0, T_UQUAD},
|
||
|
{"\002""T1", CV_ALPHA_IntT1, T_UQUAD},
|
||
|
{"\002""T2", CV_ALPHA_IntT2, T_UQUAD},
|
||
|
{"\002""T3", CV_ALPHA_IntT3, T_UQUAD},
|
||
|
{"\002""T4", CV_ALPHA_IntT4, T_UQUAD},
|
||
|
{"\002""T5", CV_ALPHA_IntT5, T_UQUAD},
|
||
|
{"\002""T6", CV_ALPHA_IntT6, T_UQUAD},
|
||
|
{"\002""T7", CV_ALPHA_IntT7, T_UQUAD},
|
||
|
{"\002""T8", CV_ALPHA_IntT8, T_UQUAD},
|
||
|
{"\002""T9", CV_ALPHA_IntT9, T_UQUAD},
|
||
|
{"\003""T10", CV_ALPHA_IntT10, T_UQUAD},
|
||
|
{"\003""T11", CV_ALPHA_IntT11, T_UQUAD},
|
||
|
{"\003""T12", CV_ALPHA_IntT12, T_UQUAD},
|
||
|
{"\002""S0", CV_ALPHA_IntS0, T_UQUAD},
|
||
|
{"\002""S1", CV_ALPHA_IntS1, T_UQUAD},
|
||
|
{"\002""S2", CV_ALPHA_IntS2, T_UQUAD},
|
||
|
{"\002""S3", CV_ALPHA_IntS3, T_UQUAD},
|
||
|
{"\002""S4", CV_ALPHA_IntS4, T_UQUAD},
|
||
|
{"\002""S5", CV_ALPHA_IntS5, T_UQUAD},
|
||
|
{"\002""GP", CV_ALPHA_IntGP, T_UQUAD},
|
||
|
{"\002""SP", CV_ALPHA_IntSP, T_UQUAD},
|
||
|
{"\002""FP", CV_ALPHA_IntFP, T_UQUAD},
|
||
|
{"\004""FPCR", CV_ALPHA_Fpcr, T_UQUAD},
|
||
|
{"\002""RA", CV_ALPHA_IntRA, T_UQUAD},
|
||
|
{"\003""FIR", CV_ALPHA_Fir, T_UQUAD},
|
||
|
{"\003""PC", CV_ALPHA_Fir, T_UQUAD},
|
||
|
{"\003""PSR", CV_ALPHA_Psr, T_UQUAD},
|
||
|
{"\003""FSR", CV_ALPHA_FltFsr, T_UQUAD},
|
||
|
{"\002""F0", CV_ALPHA_FltF0, T_REAL64},
|
||
|
{"\002""F1", CV_ALPHA_FltF1, T_REAL64},
|
||
|
{"\002""F2", CV_ALPHA_FltF2, T_REAL64},
|
||
|
{"\002""F3", CV_ALPHA_FltF3, T_REAL64},
|
||
|
{"\002""F4", CV_ALPHA_FltF4, T_REAL64},
|
||
|
{"\002""F5", CV_ALPHA_FltF5, T_REAL64},
|
||
|
{"\002""F6", CV_ALPHA_FltF6, T_REAL64},
|
||
|
{"\002""F7", CV_ALPHA_FltF7, T_REAL64},
|
||
|
{"\002""F8", CV_ALPHA_FltF8, T_REAL64},
|
||
|
{"\002""F9", CV_ALPHA_FltF9, T_REAL64},
|
||
|
{"\003""F10", CV_ALPHA_FltF10, T_REAL64},
|
||
|
{"\003""F11", CV_ALPHA_FltF11, T_REAL64},
|
||
|
{"\003""F12", CV_ALPHA_FltF12, T_REAL64},
|
||
|
{"\003""F13", CV_ALPHA_FltF13, T_REAL64},
|
||
|
{"\003""F14", CV_ALPHA_FltF14, T_REAL64},
|
||
|
{"\003""F15", CV_ALPHA_FltF15, T_REAL64},
|
||
|
{"\003""F16", CV_ALPHA_FltF16, T_REAL64},
|
||
|
{"\003""F17", CV_ALPHA_FltF17, T_REAL64},
|
||
|
{"\003""F18", CV_ALPHA_FltF18, T_REAL64},
|
||
|
{"\003""F19", CV_ALPHA_FltF19, T_REAL64},
|
||
|
{"\003""F20", CV_ALPHA_FltF20, T_REAL64},
|
||
|
{"\003""F21", CV_ALPHA_FltF21, T_REAL64},
|
||
|
{"\003""F22", CV_ALPHA_FltF22, T_REAL64},
|
||
|
{"\003""F23", CV_ALPHA_FltF23, T_REAL64},
|
||
|
{"\003""F24", CV_ALPHA_FltF24, T_REAL64},
|
||
|
{"\003""F25", CV_ALPHA_FltF25, T_REAL64},
|
||
|
{"\003""F26", CV_ALPHA_FltF26, T_REAL64},
|
||
|
{"\003""F27", CV_ALPHA_FltF27, T_REAL64},
|
||
|
{"\003""F28", CV_ALPHA_FltF28, T_REAL64},
|
||
|
{"\003""F29", CV_ALPHA_FltF29, T_REAL64},
|
||
|
{"\003""F30", CV_ALPHA_FltF30, T_REAL64},
|
||
|
{"\003""F31", CV_ALPHA_FltF31, T_REAL64},
|
||
|
};
|
||
|
|
||
|
struct hreg_ia64 {
|
||
|
char name[9]; //v-vadimp we have "BSPSTORE"
|
||
|
int index;
|
||
|
CV_typ_t type;
|
||
|
} hreg_list_ia64[] = {
|
||
|
// First, the pseudo registers
|
||
|
|
||
|
{"\x002""$p", CV_REG_PSEUDO1, T_ULONG},
|
||
|
{"\x003""$p1", CV_REG_PSEUDO1, T_ULONG},
|
||
|
{"\x003""$p2", CV_REG_PSEUDO2, T_ULONG},
|
||
|
{"\x003""$p3", CV_REG_PSEUDO3, T_ULONG},
|
||
|
{"\x003""$p4", CV_REG_PSEUDO4, T_ULONG},
|
||
|
{"\x002""$u", CV_REG_PSEUDO5, T_ULONG},
|
||
|
{"\x003""$u1", CV_REG_PSEUDO5, T_ULONG},
|
||
|
{"\x003""$u2", CV_REG_PSEUDO6, T_ULONG},
|
||
|
{"\x003""$u3", CV_REG_PSEUDO7, T_ULONG},
|
||
|
{"\x003""$u4", CV_REG_PSEUDO8, T_ULONG},
|
||
|
{"\x004""$exp", CV_REG_PSEUDO9, T_ULONG},
|
||
|
|
||
|
// Then the IA64 registers.
|
||
|
|
||
|
{"\004""BRRP", CV_IA64_BrRp, T_UQUAD },
|
||
|
{"\004""BRS0", CV_IA64_BrS0, T_UQUAD },
|
||
|
{"\004""BRS1", CV_IA64_BrS1, T_UQUAD },
|
||
|
{"\004""BRS2", CV_IA64_BrS2, T_UQUAD },
|
||
|
{"\004""BRS3", CV_IA64_BrS3, T_UQUAD },
|
||
|
{"\004""BRS4", CV_IA64_BrS4, T_UQUAD },
|
||
|
{"\004""BRT0", CV_IA64_BrT0, T_UQUAD },
|
||
|
{"\004""BRT1", CV_IA64_BrT1, T_UQUAD },
|
||
|
|
||
|
|
||
|
{"\005""PREDS", CV_IA64_Preds, T_UQUAD},
|
||
|
// {"\002""P0", CV_IA64_P0, T_BIT },
|
||
|
// {"\002""P1", CV_IA64_P1, T_BIT },
|
||
|
// {"\002""P2", CV_IA64_P2, T_BIT },
|
||
|
// {"\002""P3", CV_IA64_P3, T_BIT },
|
||
|
// {"\002""P4", CV_IA64_P4, T_BIT },
|
||
|
// {"\002""P5", CV_IA64_P5, T_BIT },
|
||
|
// {"\002""P6", CV_IA64_P6, T_BIT },
|
||
|
// {"\002""P7", CV_IA64_P7, T_BIT },
|
||
|
// {"\002""P8", CV_IA64_P8, T_BIT },
|
||
|
// {"\002""P9", CV_IA64_P9, T_BIT },
|
||
|
// {"\003""P10", CV_IA64_P10, T_BIT },
|
||
|
// {"\003""P11", CV_IA64_P11, T_BIT },
|
||
|
// {"\003""P12", CV_IA64_P12, T_BIT },
|
||
|
// {"\003""P13", CV_IA64_P13, T_BIT },
|
||
|
// {"\003""P14", CV_IA64_P14, T_BIT },
|
||
|
// {"\003""P15", CV_IA64_P15, T_BIT },
|
||
|
// {"\003""P16", CV_IA64_P16, T_BIT },
|
||
|
// {"\003""P17", CV_IA64_P17, T_BIT },
|
||
|
// {"\003""P18", CV_IA64_P18, T_BIT },
|
||
|
// {"\003""P19", CV_IA64_P19, T_BIT },
|
||
|
// {"\003""P20", CV_IA64_P20, T_BIT },
|
||
|
// {"\003""P21", CV_IA64_P21, T_BIT },
|
||
|
// {"\003""P22", CV_IA64_P22, T_BIT },
|
||
|
// {"\003""P23", CV_IA64_P23, T_BIT },
|
||
|
// {"\003""P24", CV_IA64_P24, T_BIT },
|
||
|
// {"\003""P25", CV_IA64_P25, T_BIT },
|
||
|
// {"\003""P26", CV_IA64_P26, T_BIT },
|
||
|
// {"\003""P27", CV_IA64_P27, T_BIT },
|
||
|
// {"\003""P28", CV_IA64_P28, T_BIT },
|
||
|
// {"\003""P29", CV_IA64_P29, T_BIT },
|
||
|
// {"\003""P30", CV_IA64_P30, T_BIT },
|
||
|
// {"\003""P31", CV_IA64_P31, T_BIT },
|
||
|
// {"\003""P32", CV_IA64_P32, T_BIT },
|
||
|
// {"\003""P33", CV_IA64_P33, T_BIT },
|
||
|
// {"\003""P34", CV_IA64_P34, T_BIT },
|
||
|
// {"\003""P35", CV_IA64_P35, T_BIT },
|
||
|
// {"\003""P36", CV_IA64_P36, T_BIT },
|
||
|
// {"\003""P37", CV_IA64_P37, T_BIT },
|
||
|
// {"\003""P38", CV_IA64_P38, T_BIT },
|
||
|
// {"\003""P39", CV_IA64_P39, T_BIT },
|
||
|
// {"\003""P40", CV_IA64_P40, T_BIT },
|
||
|
// {"\003""P41", CV_IA64_P41, T_BIT },
|
||
|
// {"\003""P42", CV_IA64_P42, T_BIT },
|
||
|
// {"\003""P43", CV_IA64_P43, T_BIT },
|
||
|
// {"\003""P44", CV_IA64_P44, T_BIT },
|
||
|
// {"\003""P45", CV_IA64_P45, T_BIT },
|
||
|
// {"\003""P46", CV_IA64_P46, T_BIT },
|
||
|
// {"\003""P47", CV_IA64_P47, T_BIT },
|
||
|
// {"\003""P48", CV_IA64_P48, T_BIT },
|
||
|
// {"\003""P49", CV_IA64_P49, T_BIT },
|
||
|
// {"\003""P50", CV_IA64_P50, T_BIT },
|
||
|
// {"\003""P51", CV_IA64_P51, T_BIT },
|
||
|
// {"\003""P52", CV_IA64_P52, T_BIT },
|
||
|
// {"\003""P53", CV_IA64_P53, T_BIT },
|
||
|
// {"\003""P54", CV_IA64_P54, T_BIT },
|
||
|
// {"\003""P55", CV_IA64_P55, T_BIT },
|
||
|
// {"\003""P56", CV_IA64_P56, T_BIT },
|
||
|
// {"\003""P57", CV_IA64_P57, T_BIT },
|
||
|
// {"\003""P58", CV_IA64_P58, T_BIT },
|
||
|
// {"\003""P59", CV_IA64_P59, T_BIT },
|
||
|
// {"\003""P60", CV_IA64_P60, T_BIT },
|
||
|
// {"\003""P61", CV_IA64_P61, T_BIT },
|
||
|
// {"\003""P62", CV_IA64_P62, T_BIT },
|
||
|
// {"\003""P63", CV_IA64_P63, T_BIT },
|
||
|
|
||
|
{"\002""IP", CV_IA64_Ip, T_UQUAD },
|
||
|
{"\004""NATS", CV_IA64_IntNats, T_UQUAD },
|
||
|
{"\003""CFM", CV_IA64_Cfm, T_UQUAD },
|
||
|
{"\003""PSR", CV_IA64_Psr, T_UQUAD },
|
||
|
|
||
|
{"\004""ZERO", CV_IA64_IntZero, T_UQUAD },
|
||
|
{"\002""GP", CV_IA64_IntGp, T_UQUAD },
|
||
|
{"\002""T0", CV_IA64_IntT0, T_UQUAD },
|
||
|
{"\002""T1", CV_IA64_IntT1, T_UQUAD },
|
||
|
{"\002""S0", CV_IA64_IntS0, T_UQUAD },
|
||
|
{"\002""S1", CV_IA64_IntS1, T_UQUAD },
|
||
|
{"\002""S2", CV_IA64_IntS2, T_UQUAD },
|
||
|
{"\002""S3", CV_IA64_IntS3, T_UQUAD },
|
||
|
{"\002""V0", CV_IA64_IntV0, T_UQUAD },
|
||
|
{"\002""Teb", CV_IA64_IntTeb, T_UQUAD },
|
||
|
{"\002""T2", CV_IA64_IntT2, T_UQUAD },
|
||
|
{"\002""T3", CV_IA64_IntT3, T_UQUAD },
|
||
|
{"\002""SP", CV_IA64_IntSp, T_UQUAD },
|
||
|
{"\002""T4", CV_IA64_IntT4, T_UQUAD },
|
||
|
{"\002""T5", CV_IA64_IntT5, T_UQUAD },
|
||
|
{"\002""T6", CV_IA64_IntT6, T_UQUAD },
|
||
|
{"\002""T7", CV_IA64_IntT7, T_UQUAD },
|
||
|
{"\002""T8", CV_IA64_IntT8, T_UQUAD },
|
||
|
{"\002""T9", CV_IA64_IntT9, T_UQUAD },
|
||
|
{"\003""T10", CV_IA64_IntT10, T_UQUAD },
|
||
|
{"\003""T11", CV_IA64_IntT11, T_UQUAD },
|
||
|
{"\003""T12", CV_IA64_IntT12, T_UQUAD },
|
||
|
{"\003""T13", CV_IA64_IntT13, T_UQUAD },
|
||
|
{"\003""T14", CV_IA64_IntT14, T_UQUAD },
|
||
|
{"\003""T15", CV_IA64_IntT15, T_UQUAD },
|
||
|
{"\003""T16", CV_IA64_IntT16, T_UQUAD },
|
||
|
{"\003""T17", CV_IA64_IntT17, T_UQUAD },
|
||
|
{"\003""T18", CV_IA64_IntT18, T_UQUAD },
|
||
|
{"\003""T19", CV_IA64_IntT19, T_UQUAD },
|
||
|
{"\003""T20", CV_IA64_IntT20, T_UQUAD },
|
||
|
{"\003""T21", CV_IA64_IntT21, T_UQUAD },
|
||
|
{"\003""T22", CV_IA64_IntT22, T_UQUAD },
|
||
|
|
||
|
{"\003""R32", CV_IA64_IntR32, T_UQUAD },
|
||
|
{"\003""R33", CV_IA64_IntR33, T_UQUAD },
|
||
|
{"\003""R34", CV_IA64_IntR34, T_UQUAD },
|
||
|
{"\003""R35", CV_IA64_IntR35, T_UQUAD },
|
||
|
{"\003""R36", CV_IA64_IntR36, T_UQUAD },
|
||
|
{"\003""R37", CV_IA64_IntR37, T_UQUAD },
|
||
|
{"\003""R38", CV_IA64_IntR38, T_UQUAD },
|
||
|
{"\003""R39", CV_IA64_IntR39, T_UQUAD },
|
||
|
{"\003""R40", CV_IA64_IntR40, T_UQUAD },
|
||
|
{"\003""R41", CV_IA64_IntR41, T_UQUAD },
|
||
|
{"\003""R42", CV_IA64_IntR42, T_UQUAD },
|
||
|
{"\003""R43", CV_IA64_IntR43, T_UQUAD },
|
||
|
{"\003""R44", CV_IA64_IntR44, T_UQUAD },
|
||
|
{"\003""R45", CV_IA64_IntR45, T_UQUAD },
|
||
|
{"\003""R46", CV_IA64_IntR46, T_UQUAD },
|
||
|
{"\003""R47", CV_IA64_IntR47, T_UQUAD },
|
||
|
{"\003""R48", CV_IA64_IntR48, T_UQUAD },
|
||
|
{"\003""R49", CV_IA64_IntR49, T_UQUAD },
|
||
|
{"\003""R50", CV_IA64_IntR50, T_UQUAD },
|
||
|
{"\003""R51", CV_IA64_IntR51, T_UQUAD },
|
||
|
{"\003""R52", CV_IA64_IntR52, T_UQUAD },
|
||
|
{"\003""R53", CV_IA64_IntR53, T_UQUAD },
|
||
|
{"\003""R54", CV_IA64_IntR54, T_UQUAD },
|
||
|
{"\003""R55", CV_IA64_IntR55, T_UQUAD },
|
||
|
{"\003""R56", CV_IA64_IntR56, T_UQUAD },
|
||
|
{"\003""R57", CV_IA64_IntR57, T_UQUAD },
|
||
|
{"\003""R58", CV_IA64_IntR58, T_UQUAD },
|
||
|
{"\003""R59", CV_IA64_IntR59, T_UQUAD },
|
||
|
{"\003""R60", CV_IA64_IntR60, T_UQUAD },
|
||
|
{"\003""R61", CV_IA64_IntR61, T_UQUAD },
|
||
|
{"\003""R62", CV_IA64_IntR62, T_UQUAD },
|
||
|
{"\003""R63", CV_IA64_IntR63, T_UQUAD },
|
||
|
{"\003""R64", CV_IA64_IntR64, T_UQUAD },
|
||
|
{"\003""R65", CV_IA64_IntR65, T_UQUAD },
|
||
|
{"\003""R66", CV_IA64_IntR66, T_UQUAD },
|
||
|
{"\003""R67", CV_IA64_IntR67, T_UQUAD },
|
||
|
{"\003""R68", CV_IA64_IntR68, T_UQUAD },
|
||
|
{"\003""R69", CV_IA64_IntR69, T_UQUAD },
|
||
|
{"\003""R70", CV_IA64_IntR70, T_UQUAD },
|
||
|
{"\003""R71", CV_IA64_IntR71, T_UQUAD },
|
||
|
{"\003""R72", CV_IA64_IntR72, T_UQUAD },
|
||
|
{"\003""R73", CV_IA64_IntR73, T_UQUAD },
|
||
|
{"\003""R74", CV_IA64_IntR74, T_UQUAD },
|
||
|
{"\003""R75", CV_IA64_IntR75, T_UQUAD },
|
||
|
{"\003""R76", CV_IA64_IntR76, T_UQUAD },
|
||
|
{"\003""R77", CV_IA64_IntR77, T_UQUAD },
|
||
|
{"\003""R78", CV_IA64_IntR78, T_UQUAD },
|
||
|
{"\003""R79", CV_IA64_IntR79, T_UQUAD },
|
||
|
{"\003""R80", CV_IA64_IntR80, T_UQUAD },
|
||
|
{"\003""R81", CV_IA64_IntR81, T_UQUAD },
|
||
|
{"\003""R82", CV_IA64_IntR82, T_UQUAD },
|
||
|
{"\003""R83", CV_IA64_IntR83, T_UQUAD },
|
||
|
{"\003""R84", CV_IA64_IntR84, T_UQUAD },
|
||
|
{"\003""R85", CV_IA64_IntR85, T_UQUAD },
|
||
|
{"\003""R86", CV_IA64_IntR86, T_UQUAD },
|
||
|
{"\003""R87", CV_IA64_IntR87, T_UQUAD },
|
||
|
{"\003""R88", CV_IA64_IntR88, T_UQUAD },
|
||
|
{"\003""R89", CV_IA64_IntR89, T_UQUAD },
|
||
|
{"\003""R90", CV_IA64_IntR90, T_UQUAD },
|
||
|
{"\003""R91", CV_IA64_IntR91, T_UQUAD },
|
||
|
{"\003""R92", CV_IA64_IntR92, T_UQUAD },
|
||
|
{"\003""R93", CV_IA64_IntR93, T_UQUAD },
|
||
|
{"\003""R94", CV_IA64_IntR94, T_UQUAD },
|
||
|
{"\003""R95", CV_IA64_IntR95, T_UQUAD },
|
||
|
{"\003""R96", CV_IA64_IntR96, T_UQUAD },
|
||
|
{"\003""R97", CV_IA64_IntR97, T_UQUAD },
|
||
|
{"\003""R98", CV_IA64_IntR98, T_UQUAD },
|
||
|
{"\003""R99", CV_IA64_IntR99, T_UQUAD },
|
||
|
{"\004""R100", CV_IA64_IntR100, T_UQUAD },
|
||
|
{"\004""R101", CV_IA64_IntR101, T_UQUAD },
|
||
|
{"\004""R102", CV_IA64_IntR102, T_UQUAD },
|
||
|
{"\004""R103", CV_IA64_IntR103, T_UQUAD },
|
||
|
{"\004""R104", CV_IA64_IntR104, T_UQUAD },
|
||
|
{"\004""R105", CV_IA64_IntR105, T_UQUAD },
|
||
|
{"\004""R106", CV_IA64_IntR106, T_UQUAD },
|
||
|
{"\004""R107", CV_IA64_IntR107, T_UQUAD },
|
||
|
{"\004""R108", CV_IA64_IntR108, T_UQUAD },
|
||
|
{"\004""R109", CV_IA64_IntR109, T_UQUAD },
|
||
|
{"\004""R110", CV_IA64_IntR110, T_UQUAD },
|
||
|
{"\004""R111", CV_IA64_IntR111, T_UQUAD },
|
||
|
{"\004""R112", CV_IA64_IntR112, T_UQUAD },
|
||
|
{"\004""R113", CV_IA64_IntR113, T_UQUAD },
|
||
|
{"\004""R114", CV_IA64_IntR114, T_UQUAD },
|
||
|
{"\004""R115", CV_IA64_IntR115, T_UQUAD },
|
||
|
{"\004""R116", CV_IA64_IntR116, T_UQUAD },
|
||
|
{"\004""R117", CV_IA64_IntR117, T_UQUAD },
|
||
|
{"\004""R118", CV_IA64_IntR118, T_UQUAD },
|
||
|
{"\004""R119", CV_IA64_IntR119, T_UQUAD },
|
||
|
{"\004""R120", CV_IA64_IntR120, T_UQUAD },
|
||
|
{"\004""R121", CV_IA64_IntR121, T_UQUAD },
|
||
|
{"\004""R122", CV_IA64_IntR122, T_UQUAD },
|
||
|
{"\004""R123", CV_IA64_IntR123, T_UQUAD },
|
||
|
{"\004""R124", CV_IA64_IntR124, T_UQUAD },
|
||
|
{"\004""R125", CV_IA64_IntR125, T_UQUAD },
|
||
|
{"\004""R126", CV_IA64_IntR126, T_UQUAD },
|
||
|
{"\004""R127", CV_IA64_IntR127, T_UQUAD },
|
||
|
|
||
|
|
||
|
{"\005""FZERO", CV_IA64_FltZero, T_REAL80 },
|
||
|
{"\004""FONE", CV_IA64_FltOne, T_REAL80 },
|
||
|
{"\003""FS0", CV_IA64_FltS0, T_REAL80 },
|
||
|
{"\003""FS1", CV_IA64_FltS1, T_REAL80 },
|
||
|
{"\003""FS2", CV_IA64_FltS2, T_REAL80 },
|
||
|
{"\003""FS3", CV_IA64_FltS3, T_REAL80 },
|
||
|
{"\003""FT0", CV_IA64_FltT0, T_REAL80 },
|
||
|
{"\003""FT1", CV_IA64_FltT1, T_REAL80 },
|
||
|
{"\003""FT2", CV_IA64_FltT2, T_REAL80 },
|
||
|
{"\003""FT3", CV_IA64_FltT3, T_REAL80 },
|
||
|
{"\003""FT4", CV_IA64_FltT4, T_REAL80 },
|
||
|
{"\003""FT5", CV_IA64_FltT5, T_REAL80 },
|
||
|
{"\003""FT6", CV_IA64_FltT6, T_REAL80 },
|
||
|
{"\003""FT7", CV_IA64_FltT7, T_REAL80 },
|
||
|
{"\003""FT8", CV_IA64_FltT8, T_REAL80 },
|
||
|
{"\003""FT9", CV_IA64_FltT9, T_REAL80 },
|
||
|
{"\003""FS4", CV_IA64_FltS4, T_REAL80 },
|
||
|
{"\003""FS5", CV_IA64_FltS5, T_REAL80 },
|
||
|
{"\003""FS6", CV_IA64_FltS6, T_REAL80 },
|
||
|
{"\003""FS7", CV_IA64_FltS7, T_REAL80 },
|
||
|
{"\003""FS8", CV_IA64_FltS8, T_REAL80 },
|
||
|
{"\003""FS9", CV_IA64_FltS9, T_REAL80 },
|
||
|
{"\004""FS10", CV_IA64_FltS10, T_REAL80 },
|
||
|
{"\004""FS11", CV_IA64_FltS11, T_REAL80 },
|
||
|
{"\004""FS12", CV_IA64_FltS12, T_REAL80 },
|
||
|
{"\004""FS13", CV_IA64_FltS13, T_REAL80 },
|
||
|
{"\004""FS14", CV_IA64_FltS14, T_REAL80 },
|
||
|
{"\004""FS15", CV_IA64_FltS15, T_REAL80 },
|
||
|
{"\004""FS16", CV_IA64_FltS16, T_REAL80 },
|
||
|
{"\004""FS17", CV_IA64_FltS17, T_REAL80 },
|
||
|
{"\004""FS18", CV_IA64_FltS18, T_REAL80 },
|
||
|
{"\004""FS19", CV_IA64_FltS19, T_REAL80 },
|
||
|
|
||
|
{"\003""F32", CV_IA64_FltF32, T_REAL80 },
|
||
|
{"\003""F33", CV_IA64_FltF33, T_REAL80 },
|
||
|
{"\003""F34", CV_IA64_FltF34, T_REAL80 },
|
||
|
{"\003""F35", CV_IA64_FltF35, T_REAL80 },
|
||
|
{"\003""F36", CV_IA64_FltF36, T_REAL80 },
|
||
|
{"\003""F37", CV_IA64_FltF37, T_REAL80 },
|
||
|
{"\003""F38", CV_IA64_FltF38, T_REAL80 },
|
||
|
{"\003""F39", CV_IA64_FltF39, T_REAL80 },
|
||
|
{"\003""F40", CV_IA64_FltF40, T_REAL80 },
|
||
|
{"\003""F41", CV_IA64_FltF41, T_REAL80 },
|
||
|
{"\003""F42", CV_IA64_FltF42, T_REAL80 },
|
||
|
{"\003""F43", CV_IA64_FltF43, T_REAL80 },
|
||
|
{"\003""F44", CV_IA64_FltF44, T_REAL80 },
|
||
|
{"\003""F45", CV_IA64_FltF45, T_REAL80 },
|
||
|
{"\003""F46", CV_IA64_FltF46, T_REAL80 },
|
||
|
{"\003""F47", CV_IA64_FltF47, T_REAL80 },
|
||
|
{"\003""F48", CV_IA64_FltF48, T_REAL80 },
|
||
|
{"\003""F49", CV_IA64_FltF49, T_REAL80 },
|
||
|
{"\003""F50", CV_IA64_FltF50, T_REAL80 },
|
||
|
{"\003""F51", CV_IA64_FltF51, T_REAL80 },
|
||
|
{"\003""F52", CV_IA64_FltF52, T_REAL80 },
|
||
|
{"\003""F53", CV_IA64_FltF53, T_REAL80 },
|
||
|
{"\003""F54", CV_IA64_FltF54, T_REAL80 },
|
||
|
{"\003""F55", CV_IA64_FltF55, T_REAL80 },
|
||
|
{"\003""F56", CV_IA64_FltF56, T_REAL80 },
|
||
|
{"\003""F57", CV_IA64_FltF57, T_REAL80 },
|
||
|
{"\003""F58", CV_IA64_FltF58, T_REAL80 },
|
||
|
{"\003""F59", CV_IA64_FltF59, T_REAL80 },
|
||
|
{"\003""F60", CV_IA64_FltF60, T_REAL80 },
|
||
|
{"\003""F61", CV_IA64_FltF61, T_REAL80 },
|
||
|
{"\003""F62", CV_IA64_FltF62, T_REAL80 },
|
||
|
{"\003""F63", CV_IA64_FltF63, T_REAL80 },
|
||
|
{"\003""F64", CV_IA64_FltF64, T_REAL80 },
|
||
|
{"\003""F65", CV_IA64_FltF65, T_REAL80 },
|
||
|
{"\003""F66", CV_IA64_FltF66, T_REAL80 },
|
||
|
{"\003""F67", CV_IA64_FltF67, T_REAL80 },
|
||
|
{"\003""F68", CV_IA64_FltF68, T_REAL80 },
|
||
|
{"\003""F69", CV_IA64_FltF69, T_REAL80 },
|
||
|
{"\003""F70", CV_IA64_FltF70, T_REAL80 },
|
||
|
{"\003""F71", CV_IA64_FltF71, T_REAL80 },
|
||
|
{"\003""F72", CV_IA64_FltF72, T_REAL80 },
|
||
|
{"\003""F73", CV_IA64_FltF73, T_REAL80 },
|
||
|
{"\003""F74", CV_IA64_FltF74, T_REAL80 },
|
||
|
{"\003""F75", CV_IA64_FltF75, T_REAL80 },
|
||
|
{"\003""F76", CV_IA64_FltF76, T_REAL80 },
|
||
|
{"\003""F77", CV_IA64_FltF77, T_REAL80 },
|
||
|
{"\003""F78", CV_IA64_FltF78, T_REAL80 },
|
||
|
{"\003""F79", CV_IA64_FltF79, T_REAL80 },
|
||
|
{"\003""F80", CV_IA64_FltF80, T_REAL80 },
|
||
|
{"\003""F81", CV_IA64_FltF81, T_REAL80 },
|
||
|
{"\003""F82", CV_IA64_FltF82, T_REAL80 },
|
||
|
{"\003""F83", CV_IA64_FltF83, T_REAL80 },
|
||
|
{"\003""F84", CV_IA64_FltF84, T_REAL80 },
|
||
|
{"\003""F85", CV_IA64_FltF85, T_REAL80 },
|
||
|
{"\003""F86", CV_IA64_FltF86, T_REAL80 },
|
||
|
{"\003""F87", CV_IA64_FltF87, T_REAL80 },
|
||
|
{"\003""F88", CV_IA64_FltF88, T_REAL80 },
|
||
|
{"\003""F89", CV_IA64_FltF89, T_REAL80 },
|
||
|
{"\003""F90", CV_IA64_FltF90, T_REAL80 },
|
||
|
{"\003""F91", CV_IA64_FltF91, T_REAL80 },
|
||
|
{"\003""F92", CV_IA64_FltF92, T_REAL80 },
|
||
|
{"\003""F93", CV_IA64_FltF93, T_REAL80 },
|
||
|
{"\003""F94", CV_IA64_FltF94, T_REAL80 },
|
||
|
{"\003""F95", CV_IA64_FltF95, T_REAL80 },
|
||
|
{"\003""F96", CV_IA64_FltF96, T_REAL80 },
|
||
|
{"\003""F97", CV_IA64_FltF97, T_REAL80 },
|
||
|
{"\003""F98", CV_IA64_FltF98, T_REAL80 },
|
||
|
{"\003""F99", CV_IA64_FltF99, T_REAL80 },
|
||
|
{"\004""F100", CV_IA64_FltF100, T_REAL80 },
|
||
|
{"\004""F101", CV_IA64_FltF101, T_REAL80 },
|
||
|
{"\004""F102", CV_IA64_FltF102, T_REAL80 },
|
||
|
{"\004""F103", CV_IA64_FltF103, T_REAL80 },
|
||
|
{"\004""F104", CV_IA64_FltF104, T_REAL80 },
|
||
|
{"\004""F105", CV_IA64_FltF105, T_REAL80 },
|
||
|
{"\004""F106", CV_IA64_FltF106, T_REAL80 },
|
||
|
{"\004""F107", CV_IA64_FltF107, T_REAL80 },
|
||
|
{"\004""F108", CV_IA64_FltF108, T_REAL80 },
|
||
|
{"\004""F109", CV_IA64_FltF109, T_REAL80 },
|
||
|
{"\004""F110", CV_IA64_FltF110, T_REAL80 },
|
||
|
{"\004""F111", CV_IA64_FltF111, T_REAL80 },
|
||
|
{"\004""F112", CV_IA64_FltF112, T_REAL80 },
|
||
|
{"\004""F113", CV_IA64_FltF113, T_REAL80 },
|
||
|
{"\004""F114", CV_IA64_FltF114, T_REAL80 },
|
||
|
{"\004""F115", CV_IA64_FltF115, T_REAL80 },
|
||
|
{"\004""F116", CV_IA64_FltF116, T_REAL80 },
|
||
|
{"\004""F117", CV_IA64_FltF117, T_REAL80 },
|
||
|
{"\004""F118", CV_IA64_FltF118, T_REAL80 },
|
||
|
{"\004""F119", CV_IA64_FltF119, T_REAL80 },
|
||
|
{"\004""F120", CV_IA64_FltF120, T_REAL80 },
|
||
|
{"\004""F121", CV_IA64_FltF121, T_REAL80 },
|
||
|
{"\004""F122", CV_IA64_FltF122, T_REAL80 },
|
||
|
{"\004""F123", CV_IA64_FltF123, T_REAL80 },
|
||
|
{"\004""F124", CV_IA64_FltF124, T_REAL80 },
|
||
|
{"\004""F125", CV_IA64_FltF125, T_REAL80 },
|
||
|
{"\004""F126", CV_IA64_FltF126, T_REAL80 },
|
||
|
{"\004""F127", CV_IA64_FltF127, T_REAL80 },
|
||
|
|
||
|
{"\003""KR0", CV_IA64_ApKR0, T_UQUAD },
|
||
|
{"\003""KR1", CV_IA64_ApKR1, T_UQUAD },
|
||
|
{"\003""KR2", CV_IA64_ApKR2, T_UQUAD },
|
||
|
{"\003""KR3", CV_IA64_ApKR3, T_UQUAD },
|
||
|
{"\003""KR4", CV_IA64_ApKR4, T_UQUAD },
|
||
|
{"\003""KR5", CV_IA64_ApKR5, T_UQUAD },
|
||
|
{"\003""KR6", CV_IA64_ApKR6, T_UQUAD },
|
||
|
{"\003""KR7", CV_IA64_ApKR7, T_UQUAD },
|
||
|
{"\003""AR8", CV_IA64_AR8, T_UQUAD },
|
||
|
{"\004""AR90", CV_IA64_AR9, T_UQUAD },
|
||
|
{"\004""AR10", CV_IA64_AR10, T_UQUAD },
|
||
|
{"\004""AR11", CV_IA64_AR11, T_UQUAD },
|
||
|
{"\004""AR12", CV_IA64_AR12, T_UQUAD },
|
||
|
{"\004""AR13", CV_IA64_AR13, T_UQUAD },
|
||
|
{"\004""AR14", CV_IA64_AR14, T_UQUAD },
|
||
|
{"\004""AR15", CV_IA64_AR15, T_UQUAD },
|
||
|
{"\003""RSC", CV_IA64_RsRSC, T_UQUAD },
|
||
|
{"\003""BSP", CV_IA64_RsBSP, T_UQUAD },
|
||
|
{"\007""BSPSTORE", CV_IA64_RsBSPSTORE, T_UQUAD },
|
||
|
{"\004""RNAT", CV_IA64_RsRNAT, T_UQUAD },
|
||
|
{"\004""AR20", CV_IA64_AR20, T_UQUAD },
|
||
|
{"\004""AR21", CV_IA64_AR21, T_UQUAD },
|
||
|
{"\004""AR22", CV_IA64_AR22, T_UQUAD },
|
||
|
{"\004""AR23", CV_IA64_AR23, T_UQUAD },
|
||
|
{"\004""AR24", CV_IA64_AR24, T_UQUAD },
|
||
|
{"\004""AR25", CV_IA64_AR25, T_UQUAD },
|
||
|
{"\004""AR26", CV_IA64_AR26, T_UQUAD },
|
||
|
{"\004""AR27", CV_IA64_AR27, T_UQUAD },
|
||
|
{"\004""AR28", CV_IA64_AR28, T_UQUAD },
|
||
|
{"\004""AR29", CV_IA64_AR29, T_UQUAD },
|
||
|
{"\004""AR30", CV_IA64_AR30, T_UQUAD },
|
||
|
{"\004""AR31", CV_IA64_AR31, T_UQUAD },
|
||
|
|
||
|
{"\003""CCV", CV_IA64_ApCCV, T_UQUAD },
|
||
|
{"\004""AR33", CV_IA64_AR33, T_UQUAD },
|
||
|
{"\004""AR34", CV_IA64_AR34, T_UQUAD },
|
||
|
{"\004""AR35", CV_IA64_AR35, T_UQUAD },
|
||
|
{"\004""UNAT", CV_IA64_ApUNAT, T_UQUAD },
|
||
|
{"\004""AR37", CV_IA64_AR37, T_UQUAD },
|
||
|
{"\004""AR38", CV_IA64_AR38, T_UQUAD },
|
||
|
{"\004""AR39", CV_IA64_AR39, T_UQUAD },
|
||
|
{"\004""FPSR", CV_IA64_StFPSR, T_UQUAD },
|
||
|
{"\004""AR41", CV_IA64_AR41, T_UQUAD },
|
||
|
{"\004""AR42", CV_IA64_AR42, T_UQUAD },
|
||
|
{"\004""AR43", CV_IA64_AR43, T_UQUAD },
|
||
|
{"\003""ITC", CV_IA64_ApITC, T_UQUAD },
|
||
|
{"\004""AR45", CV_IA64_AR45, T_UQUAD },
|
||
|
{"\004""AR46", CV_IA64_AR46, T_UQUAD },
|
||
|
{"\004""AR47", CV_IA64_AR47, T_UQUAD },
|
||
|
{"\004""AR48", CV_IA64_AR48, T_UQUAD },
|
||
|
{"\004""AR49", CV_IA64_AR49, T_UQUAD },
|
||
|
{"\004""AR50", CV_IA64_AR50, T_UQUAD },
|
||
|
{"\004""AR51", CV_IA64_AR51, T_UQUAD },
|
||
|
{"\004""AR52", CV_IA64_AR52, T_UQUAD },
|
||
|
{"\004""AR53", CV_IA64_AR53, T_UQUAD },
|
||
|
{"\004""AR54", CV_IA64_AR54, T_UQUAD },
|
||
|
{"\004""AR55", CV_IA64_AR55, T_UQUAD },
|
||
|
{"\004""AR56", CV_IA64_AR56, T_UQUAD },
|
||
|
{"\004""AR57", CV_IA64_AR57, T_UQUAD },
|
||
|
{"\004""AR58", CV_IA64_AR58, T_UQUAD },
|
||
|
{"\004""AR59", CV_IA64_AR59, T_UQUAD },
|
||
|
{"\004""AR60", CV_IA64_AR60, T_UQUAD },
|
||
|
{"\004""AR61", CV_IA64_AR61, T_UQUAD },
|
||
|
{"\004""AR62", CV_IA64_AR62, T_UQUAD },
|
||
|
{"\004""AR63", CV_IA64_AR63, T_UQUAD },
|
||
|
{"\003""PFS", CV_IA64_RsPFS, T_UQUAD },
|
||
|
{"\002""LC", CV_IA64_ApLC, T_UQUAD },
|
||
|
{"\002""EC", CV_IA64_ApEC, T_UQUAD },
|
||
|
{"\004""AR67", CV_IA64_AR67, T_UQUAD },
|
||
|
{"\004""AR68", CV_IA64_AR68, T_UQUAD },
|
||
|
{"\004""AR69", CV_IA64_AR69, T_UQUAD },
|
||
|
{"\004""AR70", CV_IA64_AR70, T_UQUAD },
|
||
|
{"\004""AR71", CV_IA64_AR71, T_UQUAD },
|
||
|
{"\004""AR72", CV_IA64_AR72, T_UQUAD },
|
||
|
{"\004""AR73", CV_IA64_AR73, T_UQUAD },
|
||
|
{"\004""AR74", CV_IA64_AR74, T_UQUAD },
|
||
|
{"\004""AR75", CV_IA64_AR75, T_UQUAD },
|
||
|
{"\004""AR76", CV_IA64_AR76, T_UQUAD },
|
||
|
{"\004""AR77", CV_IA64_AR77, T_UQUAD },
|
||
|
{"\004""AR78", CV_IA64_AR78, T_UQUAD },
|
||
|
{"\004""AR79", CV_IA64_AR79, T_UQUAD },
|
||
|
{"\004""AR80", CV_IA64_AR80, T_UQUAD },
|
||
|
{"\004""AR81", CV_IA64_AR81, T_UQUAD },
|
||
|
{"\004""AR82", CV_IA64_AR82, T_UQUAD },
|
||
|
{"\004""AR83", CV_IA64_AR83, T_UQUAD },
|
||
|
{"\004""AR84", CV_IA64_AR84, T_UQUAD },
|
||
|
{"\004""AR85", CV_IA64_AR85, T_UQUAD },
|
||
|
{"\004""AR86", CV_IA64_AR86, T_UQUAD },
|
||
|
{"\004""AR87", CV_IA64_AR87, T_UQUAD },
|
||
|
{"\004""AR88", CV_IA64_AR88, T_UQUAD },
|
||
|
{"\004""AR89", CV_IA64_AR89, T_UQUAD },
|
||
|
{"\004""AR90", CV_IA64_AR90, T_UQUAD },
|
||
|
{"\004""AR91", CV_IA64_AR91, T_UQUAD },
|
||
|
{"\004""AR92", CV_IA64_AR92, T_UQUAD },
|
||
|
{"\004""AR93", CV_IA64_AR93, T_UQUAD },
|
||
|
{"\004""AR94", CV_IA64_AR94, T_UQUAD },
|
||
|
{"\004""AR95", CV_IA64_AR95, T_UQUAD },
|
||
|
{"\004""AR96", CV_IA64_AR96, T_UQUAD },
|
||
|
{"\004""AR97", CV_IA64_AR97, T_UQUAD },
|
||
|
{"\004""AR98", CV_IA64_AR98, T_UQUAD },
|
||
|
{"\004""AR99", CV_IA64_AR99, T_UQUAD },
|
||
|
{"\005""AR100", CV_IA64_AR100, T_UQUAD },
|
||
|
{"\005""AR101", CV_IA64_AR101, T_UQUAD },
|
||
|
{"\005""AR102", CV_IA64_AR102, T_UQUAD },
|
||
|
{"\005""AR103", CV_IA64_AR103, T_UQUAD },
|
||
|
{"\005""AR104", CV_IA64_AR104, T_UQUAD },
|
||
|
{"\005""AR105", CV_IA64_AR105, T_UQUAD },
|
||
|
{"\005""AR106", CV_IA64_AR106, T_UQUAD },
|
||
|
{"\005""AR107", CV_IA64_AR107, T_UQUAD },
|
||
|
{"\005""AR108", CV_IA64_AR108, T_UQUAD },
|
||
|
{"\005""AR109", CV_IA64_AR109, T_UQUAD },
|
||
|
{"\005""AR110", CV_IA64_AR110, T_UQUAD },
|
||
|
{"\005""AR111", CV_IA64_AR111, T_UQUAD },
|
||
|
{"\005""AR112", CV_IA64_AR112, T_UQUAD },
|
||
|
{"\005""AR113", CV_IA64_AR113, T_UQUAD },
|
||
|
{"\005""AR114", CV_IA64_AR114, T_UQUAD },
|
||
|
{"\005""AR115", CV_IA64_AR115, T_UQUAD },
|
||
|
{"\005""AR116", CV_IA64_AR116, T_UQUAD },
|
||
|
{"\005""AR117", CV_IA64_AR117, T_UQUAD },
|
||
|
{"\005""AR118", CV_IA64_AR118, T_UQUAD },
|
||
|
{"\005""AR119", CV_IA64_AR119, T_UQUAD },
|
||
|
{"\005""AR120", CV_IA64_AR120, T_UQUAD },
|
||
|
{"\005""AR121", CV_IA64_AR121, T_UQUAD },
|
||
|
{"\005""AR122", CV_IA64_AR122, T_UQUAD },
|
||
|
{"\005""AR123", CV_IA64_AR123, T_UQUAD },
|
||
|
{"\005""AR124", CV_IA64_AR124, T_UQUAD },
|
||
|
{"\005""AR125", CV_IA64_AR125, T_UQUAD },
|
||
|
{"\005""AR126", CV_IA64_AR126, T_UQUAD },
|
||
|
{"\005""AR127", CV_IA64_AR127, T_UQUAD },
|
||
|
|
||
|
{"\003""DCR", CV_IA64_ApDCR, T_UQUAD },
|
||
|
{"\003""ITM", CV_IA64_ApITM, T_UQUAD },
|
||
|
{"\003""IVA", CV_IA64_ApIVA, T_UQUAD },
|
||
|
{"\003""CR3", CV_IA64_CR3, T_UQUAD },
|
||
|
{"\003""CR4", CV_IA64_CR4, T_UQUAD },
|
||
|
{"\003""CR5", CV_IA64_CR5, T_UQUAD },
|
||
|
{"\003""CR6", CV_IA64_CR6, T_UQUAD },
|
||
|
{"\003""CR7", CV_IA64_CR7, T_UQUAD },
|
||
|
{"\003""PTA", CV_IA64_ApPTA, T_UQUAD },
|
||
|
{"\003""CR9", CV_IA64_CR9, T_UQUAD },
|
||
|
{"\004""CR10", CV_IA64_CR10, T_UQUAD },
|
||
|
{"\004""CR11", CV_IA64_CR11, T_UQUAD },
|
||
|
{"\004""CR12", CV_IA64_CR12, T_UQUAD },
|
||
|
{"\004""CR13", CV_IA64_CR13, T_UQUAD },
|
||
|
{"\004""CR14", CV_IA64_CR14, T_UQUAD },
|
||
|
{"\004""CR15", CV_IA64_CR15, T_UQUAD },
|
||
|
{"\004""IPSR", CV_IA64_StIPSR, T_UQUAD },
|
||
|
{"\003""ISR ", CV_IA64_StISR, T_UQUAD },
|
||
|
{"\003""IDA", CV_IA64_StIDA, T_UQUAD },
|
||
|
{"\003""IIP", CV_IA64_StIIP, T_UQUAD },
|
||
|
{"\004""IDTR", CV_IA64_StIDTR, T_UQUAD },
|
||
|
{"\004""IITR", CV_IA64_StIITR, T_UQUAD },
|
||
|
{"\004""IIPA", CV_IA64_StIIPA, T_UQUAD },
|
||
|
{"\003""IFS", CV_IA64_StIFS, T_UQUAD },
|
||
|
{"\003""IIM", CV_IA64_StIIM, T_UQUAD },
|
||
|
{"\003""IHA", CV_IA64_StIHA, T_UQUAD },
|
||
|
{"\004""CR26", CV_IA64_CR26, T_UQUAD },
|
||
|
{"\004""CR27", CV_IA64_CR27, T_UQUAD },
|
||
|
{"\004""CR28", CV_IA64_CR28, T_UQUAD },
|
||
|
{"\004""CR29", CV_IA64_CR29, T_UQUAD },
|
||
|
{"\004""CR30", CV_IA64_CR30, T_UQUAD },
|
||
|
{"\004""CR31", CV_IA64_CR31, T_UQUAD },
|
||
|
|
||
|
{"\004""CR32", CV_IA64_CR32, T_UQUAD },
|
||
|
{"\004""CR33", CV_IA64_CR33, T_UQUAD },
|
||
|
{"\004""CR34", CV_IA64_CR34, T_UQUAD },
|
||
|
{"\004""CR35", CV_IA64_CR35, T_UQUAD },
|
||
|
{"\004""CR36", CV_IA64_CR36, T_UQUAD },
|
||
|
{"\004""CR37", CV_IA64_CR37, T_UQUAD },
|
||
|
{"\004""CR38", CV_IA64_CR38, T_UQUAD },
|
||
|
{"\004""CR39", CV_IA64_CR39, T_UQUAD },
|
||
|
{"\004""CR40", CV_IA64_CR40, T_UQUAD },
|
||
|
{"\004""CR41", CV_IA64_CR41, T_UQUAD },
|
||
|
{"\004""CR42", CV_IA64_CR42, T_UQUAD },
|
||
|
{"\004""CR43", CV_IA64_CR43, T_UQUAD },
|
||
|
{"\004""CR44", CV_IA64_CR44, T_UQUAD },
|
||
|
{"\004""CR45", CV_IA64_CR45, T_UQUAD },
|
||
|
{"\004""CR46", CV_IA64_CR46, T_UQUAD },
|
||
|
{"\004""CR47", CV_IA64_CR47, T_UQUAD },
|
||
|
{"\004""CR48", CV_IA64_CR48, T_UQUAD },
|
||
|
{"\004""CR49", CV_IA64_CR49, T_UQUAD },
|
||
|
{"\004""CR50", CV_IA64_CR50, T_UQUAD },
|
||
|
{"\004""CR51", CV_IA64_CR51, T_UQUAD },
|
||
|
{"\004""CR52", CV_IA64_CR52, T_UQUAD },
|
||
|
{"\004""CR53", CV_IA64_CR53, T_UQUAD },
|
||
|
{"\004""CR54", CV_IA64_CR54, T_UQUAD },
|
||
|
{"\004""CR55", CV_IA64_CR55, T_UQUAD },
|
||
|
{"\004""CR56", CV_IA64_CR56, T_UQUAD },
|
||
|
{"\004""CR57", CV_IA64_CR57, T_UQUAD },
|
||
|
{"\004""CR58", CV_IA64_CR58, T_UQUAD },
|
||
|
{"\004""CR59", CV_IA64_CR59, T_UQUAD },
|
||
|
{"\004""CR60", CV_IA64_CR60, T_UQUAD },
|
||
|
{"\004""CR61", CV_IA64_CR61, T_UQUAD },
|
||
|
{"\004""CR62", CV_IA64_CR62, T_UQUAD },
|
||
|
{"\004""CR63", CV_IA64_CR63, T_UQUAD },
|
||
|
{"\004""CR64", CV_IA64_CR64, T_UQUAD },
|
||
|
{"\004""CR65", CV_IA64_CR65, T_UQUAD },
|
||
|
{"\003""LID ", CV_IA64_SaLID, T_UQUAD },
|
||
|
{"\004""CR67", CV_IA64_CR67, T_UQUAD },
|
||
|
{"\004""CR68", CV_IA64_CR68, T_UQUAD },
|
||
|
{"\004""CR69", CV_IA64_CR69, T_UQUAD },
|
||
|
{"\004""CR70", CV_IA64_CR70, T_UQUAD },
|
||
|
{"\003""IVR ", CV_IA64_SaIVR, T_UQUAD },
|
||
|
{"\003""TPR ", CV_IA64_SaTPR, T_UQUAD },
|
||
|
{"\004""CR73", CV_IA64_CR73, T_UQUAD },
|
||
|
{"\004""CR74", CV_IA64_CR74, T_UQUAD },
|
||
|
{"\003""EOI ", CV_IA64_SaEOI, T_UQUAD },
|
||
|
{"\004""CR76", CV_IA64_CR76, T_UQUAD },
|
||
|
{"\004""CR77", CV_IA64_CR77, T_UQUAD },
|
||
|
{"\004""CR78", CV_IA64_CR78, T_UQUAD },
|
||
|
{"\004""CR79", CV_IA64_CR79, T_UQUAD },
|
||
|
{"\004""CR80", CV_IA64_CR80, T_UQUAD },
|
||
|
{"\004""CR81", CV_IA64_CR81, T_UQUAD },
|
||
|
{"\004""CR82", CV_IA64_CR82, T_UQUAD },
|
||
|
{"\004""CR83", CV_IA64_CR83, T_UQUAD },
|
||
|
{"\004""CR84", CV_IA64_CR84, T_UQUAD },
|
||
|
{"\004""CR85", CV_IA64_CR85, T_UQUAD },
|
||
|
{"\004""CR86", CV_IA64_CR86, T_UQUAD },
|
||
|
{"\004""CR87", CV_IA64_CR87, T_UQUAD },
|
||
|
{"\004""CR88", CV_IA64_CR88, T_UQUAD },
|
||
|
{"\004""CR89", CV_IA64_CR89, T_UQUAD },
|
||
|
{"\004""CR90", CV_IA64_CR90, T_UQUAD },
|
||
|
{"\004""CR91", CV_IA64_CR91, T_UQUAD },
|
||
|
{"\004""CR92", CV_IA64_CR92, T_UQUAD },
|
||
|
{"\004""CR93", CV_IA64_CR93, T_UQUAD },
|
||
|
{"\004""CR94", CV_IA64_CR94, T_UQUAD },
|
||
|
{"\004""CR95", CV_IA64_CR95, T_UQUAD },
|
||
|
{"\004""IRR0", CV_IA64_SaIRR0, T_UQUAD },
|
||
|
{"\004""CR97", CV_IA64_CR97, T_UQUAD },
|
||
|
{"\004""IRR1", CV_IA64_SaIRR1, T_UQUAD },
|
||
|
{"\004""CR99", CV_IA64_CR99, T_UQUAD },
|
||
|
{"\004""IRR2", CV_IA64_SaIRR2, T_UQUAD },
|
||
|
{"\005""CR101", CV_IA64_CR101, T_UQUAD },
|
||
|
{"\004""IRR3", CV_IA64_SaIRR3, T_UQUAD },
|
||
|
{"\005""CR103", CV_IA64_CR103, T_UQUAD },
|
||
|
{"\005""CR104", CV_IA64_CR104, T_UQUAD },
|
||
|
{"\005""CR105", CV_IA64_CR105, T_UQUAD },
|
||
|
{"\005""CR106", CV_IA64_CR106, T_UQUAD },
|
||
|
{"\005""CR107", CV_IA64_CR107, T_UQUAD },
|
||
|
{"\005""CR108", CV_IA64_CR108, T_UQUAD },
|
||
|
{"\005""CR109", CV_IA64_CR109, T_UQUAD },
|
||
|
{"\005""CR110", CV_IA64_CR110, T_UQUAD },
|
||
|
{"\005""CR111", CV_IA64_CR111, T_UQUAD },
|
||
|
{"\005""CR112", CV_IA64_CR112, T_UQUAD },
|
||
|
{"\005""CR113", CV_IA64_CR113, T_UQUAD },
|
||
|
{"\003""ITV", CV_IA64_SaITV, T_UQUAD },
|
||
|
{"\005""CR115", CV_IA64_CR115, T_UQUAD },
|
||
|
{"\003""PMV", CV_IA64_SaPMV, T_UQUAD },
|
||
|
{"\004""LRR0", CV_IA64_SaLRR0, T_UQUAD },
|
||
|
{"\004""LRR1", CV_IA64_SaLRR1, T_UQUAD },
|
||
|
{"\004""CMCV", CV_IA64_SaCMCV, T_UQUAD },
|
||
|
{"\005""CR120", CV_IA64_CR120, T_UQUAD },
|
||
|
{"\005""CR121", CV_IA64_CR121, T_UQUAD },
|
||
|
{"\005""CR122", CV_IA64_CR122, T_UQUAD },
|
||
|
{"\005""CR123", CV_IA64_CR123, T_UQUAD },
|
||
|
{"\005""CR124", CV_IA64_CR124, T_UQUAD },
|
||
|
{"\005""CR125", CV_IA64_CR125, T_UQUAD },
|
||
|
{"\005""CR126", CV_IA64_CR126, T_UQUAD },
|
||
|
{"\005""CR127", CV_IA64_CR127, T_UQUAD },
|
||
|
|
||
|
{"\004""PKR0", CV_IA64_Pkr0 , T_UQUAD },
|
||
|
{"\004""PKR1", CV_IA64_Pkr1 , T_UQUAD },
|
||
|
{"\004""PKR2", CV_IA64_Pkr2 , T_UQUAD },
|
||
|
{"\004""PKR3", CV_IA64_Pkr3 , T_UQUAD },
|
||
|
{"\004""PKR4", CV_IA64_Pkr4 , T_UQUAD },
|
||
|
{"\004""PKR5", CV_IA64_Pkr5 , T_UQUAD },
|
||
|
{"\004""PKR6", CV_IA64_Pkr6 , T_UQUAD },
|
||
|
{"\004""PKR7", CV_IA64_Pkr7 , T_UQUAD },
|
||
|
{"\004""PKR8", CV_IA64_Pkr8 , T_UQUAD },
|
||
|
{"\004""PKR9", CV_IA64_Pkr9 , T_UQUAD },
|
||
|
{"\005""PKR10", CV_IA64_Pkr10, T_UQUAD },
|
||
|
{"\005""PKR11", CV_IA64_Pkr11, T_UQUAD },
|
||
|
{"\005""PKR12", CV_IA64_Pkr12, T_UQUAD },
|
||
|
{"\005""PKR13", CV_IA64_Pkr13, T_UQUAD },
|
||
|
{"\005""PKR14", CV_IA64_Pkr14, T_UQUAD },
|
||
|
{"\005""PKR15", CV_IA64_Pkr15, T_UQUAD },
|
||
|
|
||
|
{"\003""RR0", CV_IA64_Rr0, T_UQUAD },
|
||
|
{"\003""RR1", CV_IA64_Rr1, T_UQUAD },
|
||
|
{"\003""RR2", CV_IA64_Rr2, T_UQUAD },
|
||
|
{"\003""RR3", CV_IA64_Rr3, T_UQUAD },
|
||
|
{"\003""RR4", CV_IA64_Rr4, T_UQUAD },
|
||
|
{"\003""RR5", CV_IA64_Rr5, T_UQUAD },
|
||
|
{"\003""RR6", CV_IA64_Rr6, T_UQUAD },
|
||
|
{"\003""RR7", CV_IA64_Rr7, T_UQUAD },
|
||
|
|
||
|
{"\004""PFD0", CV_IA64_PFD0, T_UQUAD },
|
||
|
{"\004""PFD1", CV_IA64_PFD1, T_UQUAD },
|
||
|
{"\004""PFD2", CV_IA64_PFD2, T_UQUAD },
|
||
|
{"\004""PFD3", CV_IA64_PFD3, T_UQUAD },
|
||
|
{"\004""PFD4", CV_IA64_PFD4, T_UQUAD },
|
||
|
{"\004""PFD5", CV_IA64_PFD5, T_UQUAD },
|
||
|
{"\004""PFD6", CV_IA64_PFD6, T_UQUAD },
|
||
|
{"\004""PFD7", CV_IA64_PFD7, T_UQUAD },
|
||
|
|
||
|
{"\004""PFC0", CV_IA64_PFC0, T_UQUAD },
|
||
|
{"\004""PFC1", CV_IA64_PFC1, T_UQUAD },
|
||
|
{"\004""PFC2", CV_IA64_PFC2, T_UQUAD },
|
||
|
{"\004""PFC3", CV_IA64_PFC3, T_UQUAD },
|
||
|
{"\004""PFC4", CV_IA64_PFC4, T_UQUAD },
|
||
|
{"\004""PFC5", CV_IA64_PFC5, T_UQUAD },
|
||
|
{"\004""PFC6", CV_IA64_PFC6, T_UQUAD },
|
||
|
{"\004""PFC7", CV_IA64_PFC7, T_UQUAD },
|
||
|
|
||
|
{"\004""TRI0", CV_IA64_TrI0, T_UQUAD },
|
||
|
{"\004""TRI1", CV_IA64_TrI1, T_UQUAD },
|
||
|
{"\004""TRI2", CV_IA64_TrI2, T_UQUAD },
|
||
|
{"\004""TRI3", CV_IA64_TrI3, T_UQUAD },
|
||
|
{"\004""TRI4", CV_IA64_TrI4, T_UQUAD },
|
||
|
{"\004""TRI5", CV_IA64_TrI5, T_UQUAD },
|
||
|
{"\004""TRI6", CV_IA64_TrI6, T_UQUAD },
|
||
|
{"\004""TRI7", CV_IA64_TrI7, T_UQUAD },
|
||
|
|
||
|
{"\004""TRD0", CV_IA64_TrD0, T_UQUAD },
|
||
|
{"\004""TRD1", CV_IA64_TrD1, T_UQUAD },
|
||
|
{"\004""TRD2", CV_IA64_TrD2, T_UQUAD },
|
||
|
{"\004""TRD3", CV_IA64_TrD3, T_UQUAD },
|
||
|
{"\004""TRD4", CV_IA64_TrD4, T_UQUAD },
|
||
|
{"\004""TRD5", CV_IA64_TrD5, T_UQUAD },
|
||
|
{"\004""TRD6", CV_IA64_TrD6, T_UQUAD },
|
||
|
{"\004""TRD7", CV_IA64_TrD7, T_UQUAD },
|
||
|
|
||
|
{"\004""DBI0", CV_IA64_DbI0, T_UQUAD },
|
||
|
{"\004""DBI1", CV_IA64_DbI1, T_UQUAD },
|
||
|
{"\004""DBI2", CV_IA64_DbI2, T_UQUAD },
|
||
|
{"\004""DBI3", CV_IA64_DbI3, T_UQUAD },
|
||
|
{"\004""DBI4", CV_IA64_DbI4, T_UQUAD },
|
||
|
{"\004""DBI5", CV_IA64_DbI5, T_UQUAD },
|
||
|
{"\004""DBI6", CV_IA64_DbI6, T_UQUAD },
|
||
|
{"\004""DBI7", CV_IA64_DbI7, T_UQUAD },
|
||
|
|
||
|
{"\004""DBD0", CV_IA64_DbD0, T_UQUAD },
|
||
|
{"\004""DBD1", CV_IA64_DbD1, T_UQUAD },
|
||
|
{"\004""DBD2", CV_IA64_DbD2, T_UQUAD },
|
||
|
{"\004""DBD3", CV_IA64_DbD3, T_UQUAD },
|
||
|
{"\004""DBD4", CV_IA64_DbD4, T_UQUAD },
|
||
|
{"\004""DBD5", CV_IA64_DbD5, T_UQUAD },
|
||
|
{"\004""DBD6", CV_IA64_DbD6, T_UQUAD },
|
||
|
{"\004""DBD7", CV_IA64_DbD7, T_UQUAD }
|
||
|
};
|
||
|
|
||
|
#define REGCNT_X86 (sizeof (hreg_list_x86)/sizeof (struct hreg_x86))
|
||
|
#define REGCNT_MIP (sizeof (hreg_list_mip)/sizeof (struct hreg_mip))
|
||
|
#define REGCNT_AXP (sizeof (hreg_list_axp)/sizeof (struct hreg_axp))
|
||
|
#define REGCNT_PPC (sizeof (hreg_list_ppc)/sizeof (struct hreg_ppc))
|
||
|
#define REGCNT_68K (sizeof (hreg_list_68k)/sizeof (struct hreg_68k))
|
||
|
#define REGCNT_IA64 (sizeof (hreg_list_ia64)/sizeof (struct hreg_ia64))
|
||
|
|
||
|
bool_t
|
||
|
ParseRegister (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
int i;
|
||
|
peval_t pv;
|
||
|
|
||
|
if (*pName->sstr.lpName == '@') {
|
||
|
pName->sstr.lpName++;
|
||
|
pName->sstr.cb--;
|
||
|
}
|
||
|
|
||
|
pv = pName->pv;
|
||
|
|
||
|
switch (TargetMachine) {
|
||
|
case mptmips:
|
||
|
for (i = 0; i < REGCNT_MIP; i++) {
|
||
|
if (fnCmp (pName, NULL, hreg_list_mip[i].name, FALSE) == 0)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (i >= REGCNT_MIP) {
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
EVAL_REG (pv) = hreg_list_mip[i].index;
|
||
|
SetNodeType (pv, hreg_list_mip[i].type);
|
||
|
EVAL_IS_HIBYTE (pv) = FALSE;
|
||
|
break;
|
||
|
|
||
|
case mptix86:
|
||
|
for (i = 0; i < REGCNT_X86; i++) {
|
||
|
if (fnCmp (pName, NULL, hreg_list_x86[i].name, FALSE) == 0)
|
||
|
break;
|
||
|
}
|
||
|
if ((i >= REGCNT_X86) ||
|
||
|
(!(hreg_list_x86[i].valid & VALIDx86) && !in386mode))
|
||
|
{
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
EVAL_REG (pv) = hreg_list_x86[i].index;
|
||
|
SetNodeType (pv, hreg_list_x86[i].type);
|
||
|
EVAL_IS_HIBYTE (pv) = ((hreg_list_x86[i].valid & REGHI) == REGHI);
|
||
|
break;
|
||
|
|
||
|
case mptia64:
|
||
|
for (i = 0; i < REGCNT_IA64; i++) {
|
||
|
if (fnCmp (pName, NULL, hreg_list_ia64[i].name, FALSE) == 0)
|
||
|
break;
|
||
|
}
|
||
|
if (i >= REGCNT_IA64)
|
||
|
{
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
EVAL_REG (pv) = hreg_list_ia64[i].index;
|
||
|
SetNodeType (pv, hreg_list_ia64[i].type);
|
||
|
EVAL_IS_HIBYTE (pv) = FALSE;
|
||
|
break;
|
||
|
|
||
|
case mptdaxp:
|
||
|
for (i = 0; i < REGCNT_AXP; i++) {
|
||
|
if (fnCmp (pName, NULL, hreg_list_axp[i].name, FALSE) == 0)
|
||
|
break;
|
||
|
}
|
||
|
if (i >= REGCNT_AXP) {
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
EVAL_REG (pv) = hreg_list_axp[i].index;
|
||
|
SetNodeType (pv, hreg_list_axp[i].type);
|
||
|
EVAL_IS_HIBYTE (pv) = FALSE;
|
||
|
break;
|
||
|
|
||
|
case mptmppc:
|
||
|
case mptntppc:
|
||
|
for (i = 0; i < REGCNT_PPC; i++) {
|
||
|
if (fnCmp (pName, NULL, hreg_list_ppc[i].name, FALSE) == 0)
|
||
|
break;
|
||
|
}
|
||
|
if (i >= REGCNT_PPC) {
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
EVAL_REG (pv) = hreg_list_ppc[i].index;
|
||
|
SetNodeType (pv, hreg_list_ppc[i].type);
|
||
|
EVAL_IS_HIBYTE (pv) = FALSE;
|
||
|
break;
|
||
|
|
||
|
case mptm68k:
|
||
|
for (i = 0; i < REGCNT_68K; i++) {
|
||
|
if (fnCmp (pName, NULL, hreg_list_68k[i].name, FALSE) == 0)
|
||
|
break;
|
||
|
}
|
||
|
if (i >= REGCNT_68K) {
|
||
|
return (HR_notfound);
|
||
|
}
|
||
|
EVAL_REG (pv) = hreg_list_68k[i].index;
|
||
|
SetNodeType (pv, hreg_list_68k[i].type);
|
||
|
EVAL_IS_HIBYTE (pv) = FALSE;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
DASSERT(FALSE);
|
||
|
}
|
||
|
|
||
|
EVAL_IS_REG (pv) = TRUE;
|
||
|
|
||
|
EVAL_STATE (pv) = EV_lvalue;
|
||
|
PushStack (pv);
|
||
|
return (HR_found);
|
||
|
}
|
||
|
|
||
|
|
||
|
bool_t
|
||
|
LineNumber (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
uchar *pb = pName->sstr.lpName + 1;
|
||
|
uint i;
|
||
|
char c;
|
||
|
ulong val = 0;
|
||
|
//FLS fls;
|
||
|
HSF hsf;
|
||
|
ADDR addr;
|
||
|
SHOFF cbLine;
|
||
|
|
||
|
peval_t pv;
|
||
|
|
||
|
// convert line number
|
||
|
|
||
|
for (i = pName->sstr.cb - 1; i > 0; i--) {
|
||
|
c = *pb;
|
||
|
if (!_istdigit ((_TUCHAR)c)) {
|
||
|
// Must have reached the end
|
||
|
pExState->err_num = ERR_LINENUMBER;
|
||
|
return (HR_error);
|
||
|
}
|
||
|
val *= 10;
|
||
|
val += (c - '0');
|
||
|
if (val > 0xffff) {
|
||
|
// Must have overflowed
|
||
|
pExState->err_num = ERR_LINENUMBER;
|
||
|
return (HR_error);
|
||
|
}
|
||
|
pb++;
|
||
|
}
|
||
|
|
||
|
if ( (hsf = SLHsfFromPcxt ( pCxt ) ) &&
|
||
|
SLFLineToAddr ( hsf, (WORD) val, &addr, &cbLine, NULL ) ) {
|
||
|
|
||
|
pv = pName->pv;
|
||
|
if ( ADDR_IS_OFF32 ( addr ) ) {
|
||
|
SetNodeType (pv, T_32PVOID);
|
||
|
}
|
||
|
else {
|
||
|
SetNodeType (pv, T_PFVOID);
|
||
|
}
|
||
|
|
||
|
EVAL_IS_LABEL (pv) = TRUE;
|
||
|
EVAL_STATE (pv) = EV_rvalue;
|
||
|
EVAL_SYM (pv) = addr;
|
||
|
EVAL_PTR (pv) = addr;
|
||
|
PushStack (pv);
|
||
|
return (HR_found);
|
||
|
}
|
||
|
else {
|
||
|
pExState->err_num = ERR_NOCODE;
|
||
|
return (HR_error);
|
||
|
}
|
||
|
|
||
|
pExState->err_num = ERR_BADCONTEXT;
|
||
|
return (HR_error);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** InsertThis - rewrite bind tree to add this->
|
||
|
|
||
|
* fSuccess = InsertThis (pName);
|
||
|
|
||
|
* Entry pName = pointer to search structure
|
||
|
|
||
|
* Exit tree rewritten such that the node pn becomes OP_pointsto
|
||
|
* with the left node being OP_this and the right node being
|
||
|
* the original symbol
|
||
|
|
||
|
* Returns TRUE if tree rewritten
|
||
|
* FALSE if error
|
||
|
*/
|
||
|
|
||
|
|
||
|
bool_t FASTCALL
|
||
|
InsertThis (
|
||
|
psearch_t pName
|
||
|
)
|
||
|
{
|
||
|
ulong len = 2 * (sizeof (node_t) + sizeof (eval_t));
|
||
|
ulong Left;
|
||
|
ulong Right;
|
||
|
pnode_t pn;
|
||
|
bnode_t bn = pName->bn;
|
||
|
|
||
|
Left = pTree->node_next;
|
||
|
Right = Left + sizeof (node_t) + sizeof (eval_t);
|
||
|
if ((pTree->size - Left) < len) {
|
||
|
if (!GrowETree (len)) {
|
||
|
NOTTESTED (FALSE);
|
||
|
pExState->err_num = ERR_NOMEMORY;
|
||
|
return (FALSE);
|
||
|
}
|
||
|
if (bnCxt != 0) {
|
||
|
// the context was pointing into the expression tree.
|
||
|
// since the expression tree could have been reallocated,
|
||
|
// we must recompute the context pointer
|
||
|
|
||
|
pCxt = SHpCXTFrompCXF ((PCXF)&((pnode_t)bnCxt)->v[0]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// copy symbol to right node
|
||
|
|
||
|
memcpy ((pnode_t)((bnode_t)Right), (pnode_t)bn, sizeof (node_t) + sizeof (eval_t));
|
||
|
|
||
|
// insert OP_this node as left node
|
||
|
|
||
|
pn = (pnode_t)((bnode_t)Left);
|
||
|
memset (pn, 0, sizeof (node_t) + sizeof (eval_t));
|
||
|
NODE_OP (pn) = OP_this;
|
||
|
|
||
|
// change original node to OP_pointsto
|
||
|
|
||
|
pn = (pnode_t)bn;
|
||
|
memset (pn, 0, sizeof (node_t) + sizeof (eval_t));
|
||
|
NODE_OP (pn) = OP_pointsto;
|
||
|
NODE_LCHILD (pn) = (bnode_t)Left;
|
||
|
NODE_RCHILD (pn) = (bnode_t)Right;
|
||
|
pTree->node_next += len;
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* load a constant symbol into a node.
|
||
|
*/
|
||
|
|
||
|
bool_t
|
||
|
DebLoadConst (
|
||
|
peval_t pv,
|
||
|
CONSTPTR pSym,
|
||
|
HSYM hSym
|
||
|
)
|
||
|
{
|
||
|
uint skip = 0;
|
||
|
CV_typ_t type;
|
||
|
HTYPE hType;
|
||
|
plfEnum pEnum;
|
||
|
|
||
|
type = pSym->typind;
|
||
|
if (!CV_IS_PRIMITIVE (type)) {
|
||
|
// we also allow constants that are enumeration values, so check
|
||
|
// that the non-primitive type is an enumeration and set the type
|
||
|
// to the underlying type of the enum
|
||
|
|
||
|
MHOmfUnLock (hSym);
|
||
|
hType = THGetTypeFromIndex (EVAL_MOD (pv), type);
|
||
|
if (hType == 0) {
|
||
|
DASSERT (FALSE);
|
||
|
pSym = (CONSTPTR) MHOmfLock (hSym);
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (FALSE);
|
||
|
}
|
||
|
pEnum = (plfEnum)(&((TYPPTR)(MHOmfLock (hType)))->leaf);
|
||
|
if ((pEnum->leaf != LF_ENUM) || !CV_IS_PRIMITIVE (pEnum->utype)) {
|
||
|
DASSERT (FALSE);
|
||
|
MHOmfUnLock (hType);
|
||
|
pSym = (CONSTPTR) MHOmfLock (hSym);
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (FALSE);
|
||
|
}
|
||
|
MHOmfUnLock (hType);
|
||
|
pSym = (CONSTPTR) MHOmfLock (hSym);
|
||
|
SetNodeType (pv, type);
|
||
|
// SetNodeType will resolve forward ref Enums - but we need to get the
|
||
|
// utype from the pv when this happens - sps
|
||
|
type = ENUM_UTYPE (pv);
|
||
|
}
|
||
|
else {
|
||
|
SetNodeType (pv, type);
|
||
|
}
|
||
|
|
||
|
EVAL_STATE (pv) = EV_rvalue;
|
||
|
if ((CV_MODE (type) != CV_TM_DIRECT) || ((CV_TYPE (type) != CV_SIGNED) &&
|
||
|
(CV_TYPE (type) != CV_UNSIGNED) && (CV_TYPE (type) != CV_INT))) {
|
||
|
DASSERT (FALSE);
|
||
|
pExState->err_num = ERR_BADOMF;
|
||
|
return (FALSE);
|
||
|
}
|
||
|
EVAL_UQUAD (pv) = RNumLeaf (&pSym->value, &skip);
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/** fValidInProlog - check if local symbol is valid in the func. prolog
|
||
|
|
||
|
* flag = fValidInProlog (hSym, fNoFrame)
|
||
|
|
||
|
* Entry hSym = handle to local symbol
|
||
|
|
||
|
* Exit none
|
||
|
|
||
|
* Returns TRUE if hSym is valid
|
||
|
* FALSE if hSym is rejectable
|
||
|
|
||
|
* A local symbol is rejectable in the prolog if it is a bp-relative
|
||
|
* or register item (since the new frame has not been set up yet)
|
||
|
* However formal arguments (e.g., bp-relative symbols with +ve
|
||
|
* offset) are not rejectable since they are already on the stack.
|
||
|
* We let such symbols bind properly during the evaluation phase
|
||
|
* the frame passed by the kernel contains a virtual bp value that
|
||
|
* points to the right address on the stack.
|
||
|
|
||
|
* NOTE: If the frame is indicated as not available then the symbol
|
||
|
* is an argument or parameter. Only labels and the like are
|
||
|
* valid without a frame...
|
||
|
*/
|
||
|
|
||
|
bool_t
|
||
|
fValidInProlog (
|
||
|
HSYM hSym,
|
||
|
bool_t fNoFrame
|
||
|
)
|
||
|
{
|
||
|
SYMPTR pSym = (SYMPTR) MHOmfLock (hSym);
|
||
|
bool_t retval;
|
||
|
|
||
|
switch (pSym->rectyp) {
|
||
|
case S_BPREL16:
|
||
|
retval = !fNoFrame && (((BPRELPTR16)pSym)->off >= 0);
|
||
|
break;
|
||
|
|
||
|
case S_BPREL32:
|
||
|
retval = !fNoFrame && (((BPRELPTR32)pSym)->off >= 0);
|
||
|
break;
|
||
|
|
||
|
case S_REGREL32:
|
||
|
if (TargetMachine == mptmips) {
|
||
|
// All offsets are SP relative not FP.
|
||
|
retval = (((LPREGREL32)pSym)->reg != CV_M4_IntSP) &&
|
||
|
(((LPREGREL32)pSym)->reg != CV_M4_IntS8);
|
||
|
} else {
|
||
|
retval = !fNoFrame && (((LPREGREL32)pSym)->off >= 0);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case S_REGISTER:
|
||
|
if (fNoFrame) return FALSE;
|
||
|
|
||
|
switch (((REGPTR)pSym)->reg) {
|
||
|
case CV_REG_ECX:
|
||
|
case CV_REG_EDX:
|
||
|
// These registers are used for fastcall arguments
|
||
|
retval = TRUE;
|
||
|
break;
|
||
|
default:
|
||
|
retval = FALSE;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
// non bp-rel, non reg-rel, non-register symbols
|
||
|
// are always considered bindable during prolog
|
||
|
retval = TRUE;
|
||
|
}
|
||
|
|
||
|
MHOmfUnLock (hSym);
|
||
|
return retval;
|
||
|
}
|