mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
811 lines
24 KiB
811 lines
24 KiB
/*** SHsymlb0.c - general library routines to find an
|
|
* omf symbol by name or address.
|
|
*
|
|
* Copyright <C> 1988, Microsoft Corporation
|
|
*
|
|
* Purpose: To supply a concise interface to the debug omf for symbols
|
|
*
|
|
*
|
|
*************************************************************************/
|
|
#include "shinc.h"
|
|
#pragma hdrstop
|
|
|
|
BOOL SHIsAddrInMod (LPMDS, LPADDR, ISECT* pisect, OFF* poff, CB* pcb);
|
|
|
|
//**********************************************************************
|
|
//**********************************************************************
|
|
|
|
// the following is local to this module ONLY! It is here to force
|
|
// existing behavior. Statics are promised to be zero filled by compiler
|
|
char SHszDir[ _MAX_CVDIR ] = {'\0'};
|
|
char SHszDrive[ _MAX_CVDRIVE ] = {'\0'};
|
|
char SHszDebuggeeDir[ _MAX_CVDIR ] = {'\0'};
|
|
char SHszDebuggeeDrive[ _MAX_CVDRIVE ] = {'\0'};
|
|
|
|
//***********************************************************************
|
|
//* *
|
|
//* fundamental source line lookup routines *
|
|
//* *
|
|
//***********************************************************************
|
|
|
|
/*** SHSetDebugeeDir
|
|
*
|
|
* Purpose: To get a pointer to the direcotr of the debuggee.
|
|
*
|
|
* Input: lszDir - A pointer to the debuggee's directory
|
|
*
|
|
* Output:
|
|
* Returns:
|
|
*
|
|
* Exceptions:
|
|
*
|
|
* Notes: Must be a zero terminated directory. No trailing \
|
|
*
|
|
*************************************************************************/
|
|
VOID LOADDS PASCAL SHSetDebuggeeDir ( LSZ lszDir ) {
|
|
|
|
LPCH lpch;
|
|
|
|
if ( lszDir ) {
|
|
|
|
lpch = lszDir;
|
|
while( *lpch && _istspace(*lpch) )
|
|
lpch = _ftcsinc( lpch );
|
|
|
|
if( *lpch && lpch[1] == ':' ) {
|
|
SHszDebuggeeDrive[0] = *lpch;
|
|
SHszDebuggeeDrive[1] = ':';
|
|
SHszDebuggeeDrive[2] = '\0';
|
|
lpch += 2; // point past the :
|
|
}
|
|
else {
|
|
SHszDebuggeeDrive[0] = '\0';
|
|
}
|
|
|
|
// copy the path
|
|
_ftcscpy ( SHszDebuggeeDir, lpch );
|
|
}
|
|
}
|
|
|
|
|
|
/*** SHpSymlplLabLoc
|
|
*
|
|
* Purpose: To completely fill in a plpl pkt. The hmod and addr must already
|
|
* be valid. The locals and labels are searched based on paddr. The
|
|
* whole module is search for now. Better decisions may be made in the
|
|
* future.
|
|
*
|
|
*
|
|
* Input:
|
|
* plpl - lpl packet with a valid module and address in it.
|
|
*
|
|
* Output:
|
|
* plpl - Is updated with Proc, Local, and Label.
|
|
*
|
|
* Returns .....
|
|
*
|
|
* Exceptions:
|
|
*
|
|
* Notes: This includes locals and lables
|
|
*
|
|
*************************************************************************/
|
|
VOID PASCAL SHpSymlplLabLoc ( LPLBS lplbs ) {
|
|
SYMPTR lpSym = NULL;
|
|
SYMPTR lpSymEnd;
|
|
LPMDS lpmds;
|
|
ULONG cbMod = 0;
|
|
CV_uoff32_t obModelMin = 0;
|
|
CV_uoff32_t obModelMax = CV_MAXOFFSET;
|
|
CV_uoff32_t obTarget;
|
|
CV_uoff32_t doffNew;
|
|
CV_uoff32_t doffOld;
|
|
|
|
// for now we are doing the whole module
|
|
|
|
lplbs->tagLoc = NULL;
|
|
lplbs->tagLab = NULL;
|
|
lplbs->tagProc = NULL;
|
|
lplbs->tagModelMin = NULL;
|
|
lplbs->tagModelMax = NULL;
|
|
|
|
if( !lplbs->tagMod ) {
|
|
return;
|
|
}
|
|
|
|
// because segments of locals don't have to match the segment of the
|
|
// searched module, check segment here is wrong. However we can set
|
|
// a flag up for proc and labels
|
|
|
|
lpmds = LLLock (lplbs->tagMod);
|
|
obTarget = GetAddrOff (lplbs->addr);
|
|
LLUnlock (lplbs->tagMod);
|
|
|
|
// add/subtract the size of the hash table ptr
|
|
lpSym = (SYMPTR) ( (LPB) GetSymbols ( lpmds ) + sizeof( long ) );
|
|
cbMod = lpmds->cbSymbols;
|
|
lpSymEnd = (SYMPTR) ( (BYTE FAR *) lpSym + cbMod - sizeof ( long ) );
|
|
|
|
while( lpSym < lpSymEnd ) {
|
|
|
|
switch( lpSym->rectyp ) {
|
|
#if defined (ADDR_16) || defined (ADDR_MIXED)
|
|
case S_CEXMODEL16:
|
|
if (((WORD)(((CEXMPTR16)lpSym)->seg) == (WORD)GetAddrSeg (lplbs->addr))) {
|
|
CV_uoff32_t obTemp = (CV_uoff32_t)(((CEXMPTR16)lpSym)->off);
|
|
if (obTemp <= obModelMax) {
|
|
if (obTemp > obTarget) {
|
|
lplbs->tagModelMax = (CEXMPTR16)lpSym;
|
|
obModelMax = obTemp;
|
|
}
|
|
else if (obTemp >= obModelMin) {
|
|
lplbs->tagModelMin = (CEXMPTR16)lpSym;
|
|
obModelMin = obTemp;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case S_LPROC16:
|
|
case S_GPROC16:
|
|
if (((WORD)(((PROCPTR16)lpSym)->seg) == (WORD)GetAddrSeg (lplbs->addr)) &&
|
|
((CV_uoff32_t)(((PROCPTR16)lpSym)->off) <= obTarget) &&
|
|
(obTarget < ((CV_uoff32_t)(((PROCPTR16)lpSym)->off) + (CV_uoff32_t)(((PROCPTR16)lpSym)->len)))) {
|
|
lplbs->tagProc = (SYMPTR)lpSym;
|
|
}
|
|
break;
|
|
|
|
case S_LABEL16:
|
|
if (((WORD)(((LABELPTR16)lpSym)->seg) == (WORD)GetAddrSeg (lplbs->addr)) &&
|
|
(((CV_uoff32_t)((LABELPTR16)lpSym)->off) <= obTarget)) {
|
|
doffNew = obTarget - (CV_uoff32_t)(((LABELPTR16)lpSym)->off);
|
|
|
|
// calculate what the old offset was, this requires no
|
|
// use of static variables
|
|
|
|
if ( lplbs->tagLab ) {
|
|
doffOld = obTarget - (CV_uoff32_t)(((LABELPTR16)lplbs->tagLab)->off);
|
|
}
|
|
else {
|
|
doffOld = obTarget;
|
|
}
|
|
|
|
if ( doffNew <= doffOld ) {
|
|
lplbs->tagLab = (SYMPTR)lpSym;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case S_LDATA16:
|
|
case S_GDATA16:
|
|
if (((WORD)(((DATAPTR16)lpSym)->seg) == (WORD)GetAddrSeg (lplbs->addr)) &&
|
|
((CV_uoff32_t)(((DATAPTR16)lpSym)->off) <= obTarget)) {
|
|
doffNew = obTarget - (CV_uoff32_t)(((DATAPTR16)lpSym)->off);
|
|
|
|
// calculate what the old offset was.
|
|
if ( lplbs->tagLoc ) {
|
|
doffOld = obTarget - (CV_uoff32_t)(((DATAPTR16)lplbs->tagLoc)->off);
|
|
}
|
|
else {
|
|
doffOld = obTarget;
|
|
}
|
|
|
|
if ( doffNew <= doffOld ) {
|
|
lplbs->tagLoc = (SYMPTR) lpSym;
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
#if defined (ADDR_32) || defined (ADDR_MIXED) || defined (TARGET32)
|
|
case S_CEXMODEL32:
|
|
if (((WORD)(((CEXMPTR32)lpSym)->seg) == (WORD)GetAddrSeg (lplbs->addr))) {
|
|
CV_uoff32_t obTemp = (CV_uoff32_t)(((CEXMPTR32)lpSym)->off);
|
|
if (obTemp <= obModelMax) {
|
|
if (obTemp > obTarget) {
|
|
lplbs->tagModelMax = (CEXMPTR16)(CEXMPTR32)lpSym;
|
|
obModelMax = obTemp;
|
|
}
|
|
else if (obTemp >= obModelMin) {
|
|
lplbs->tagModelMin = (CEXMPTR16)(CEXMPTR32)lpSym;
|
|
obModelMin = obTemp;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case S_LPROC32:
|
|
case S_GPROC32:
|
|
if (((WORD)(((PROCPTR32)lpSym)->seg) == (WORD)GetAddrSeg (lplbs->addr)) &&
|
|
((CV_uoff32_t)(((PROCPTR32)lpSym)->off) <= obTarget) &&
|
|
(obTarget < ((CV_uoff32_t)(((PROCPTR32)lpSym)->off) + (CV_uoff32_t)(((PROCPTR32)lpSym)->len)))) {
|
|
lplbs->tagProc = (SYMPTR)lpSym;
|
|
}
|
|
break;
|
|
|
|
case S_LPROCMIPS:
|
|
case S_GPROCMIPS:
|
|
if (((WORD)(((PROCPTRMIPS)lpSym)->seg) == (WORD)GetAddrSeg (lplbs->addr)) &&
|
|
((CV_uoff32_t)(((PROCPTRMIPS)lpSym)->off) <= obTarget) &&
|
|
(obTarget < ((CV_uoff32_t)(((PROCPTRMIPS)lpSym)->off) + (CV_uoff32_t)(((PROCPTRMIPS)lpSym)->len)))) {
|
|
lplbs->tagProc = (SYMPTR)lpSym;
|
|
}
|
|
break;
|
|
|
|
case S_LABEL32:
|
|
if (((WORD)(((LABELPTR32)lpSym)->seg) == (WORD)GetAddrSeg (lplbs->addr)) &&
|
|
(((CV_uoff32_t)((LABELPTR32)lpSym)->off) <= obTarget)) {
|
|
doffNew = obTarget - (CV_uoff32_t)(((LABELPTR32)lpSym)->off);
|
|
|
|
// calculate what the old offset was, this requires no
|
|
// use of static variables
|
|
|
|
if ( lplbs->tagLab ) {
|
|
doffOld = obTarget - (CV_uoff32_t)(((LABELPTR32)lplbs->tagLab)->off);
|
|
}
|
|
else {
|
|
doffOld = obTarget;
|
|
}
|
|
|
|
if ( doffNew <= doffOld ) {
|
|
lplbs->tagLab = (SYMPTR)lpSym;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case S_LDATA32:
|
|
case S_GDATA32:
|
|
case S_LTHREAD32:
|
|
case S_GTHREAD32:
|
|
if (((WORD)(((DATAPTR32)lpSym)->seg) == (WORD)GetAddrSeg (lplbs->addr)) &&
|
|
((CV_uoff32_t)(((DATAPTR32)lpSym)->off) <= obTarget)) {
|
|
doffNew = obTarget - (CV_uoff32_t)(((DATAPTR32)lpSym)->off);
|
|
|
|
// calculate what the old offset was.
|
|
if ( lplbs->tagLoc ) {
|
|
doffOld = obTarget - (CV_uoff32_t)(((DATAPTR32)lplbs->tagLoc)->off);
|
|
}
|
|
else {
|
|
doffOld = obTarget;
|
|
}
|
|
|
|
if ( doffNew <= doffOld ) {
|
|
lplbs->tagLoc = (SYMPTR) lpSym;
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
}
|
|
lpSym = NEXTSYM ( SYMPTR, lpSym );
|
|
}
|
|
|
|
// now convert to emstags
|
|
|
|
if ( lplbs->tagLoc ) {
|
|
lplbs->tagLoc = (SYMPTR) lplbs->tagLoc;
|
|
}
|
|
|
|
if ( lplbs->tagLab ) {
|
|
lplbs->tagLab = (SYMPTR) lplbs->tagLab;
|
|
}
|
|
|
|
if ( lplbs->tagProc) {
|
|
lplbs->tagProc = (SYMPTR) lplbs->tagProc;
|
|
}
|
|
|
|
if ( lplbs->tagModelMin) {
|
|
lplbs->tagModelMin = (CEXMPTR16) lplbs->tagModelMin;
|
|
}
|
|
|
|
if ( lplbs->tagModelMax) {
|
|
lplbs->tagModelMax = (CEXMPTR16) lplbs->tagModelMax;
|
|
}
|
|
}
|
|
|
|
/*** SHdNearestSymbol
|
|
*
|
|
* Purpose: To find the closest label/proc to the specified address is
|
|
* found and put in pch. Both the symbol table and the
|
|
* publics tables are searched.
|
|
*
|
|
* Input:
|
|
* ptxt - a pointer to the context, address and mdi must
|
|
* be filled in.
|
|
*
|
|
* sop - Determine what type of symbols to look for
|
|
*
|
|
* Output:
|
|
*
|
|
* Exceptions:
|
|
*
|
|
* Notes: If CV_MAXOFFSET is returned in the lpodr, there is no closest
|
|
* symbol Also all symbols in the module are searched so only the
|
|
* cxt.addr and cxt.mdi have meaning.
|
|
*
|
|
*************************************************************************/
|
|
|
|
VOID PASCAL SHdNearestSymbol ( PCXT pcxt, SOP sop, LPODR lpodr ) {
|
|
|
|
HSYM hSym;
|
|
SYMPTR pSym;
|
|
LBS lbs;
|
|
ULONG doff = CV_MAXOFFSET;
|
|
ULONG doffNew = CV_MAXOFFSET;
|
|
LPCH lpch = lpodr->lszName;
|
|
|
|
lpodr->fst = fstNone;
|
|
lpodr->fcd = fcdUnknown;
|
|
lpodr->fpt = fptUnknown;
|
|
lpodr->cbProlog = 0;
|
|
lpodr->dwDeltaOff = 0;
|
|
|
|
*lpch = '\0';
|
|
if ( SHHMODFrompCXT ( pcxt ) ) {
|
|
BOOL bAddrInProc = FALSE;
|
|
|
|
// at some point we may wish to specify only a scope to search for
|
|
// a label. So we may wish to initialize the lbs differently
|
|
|
|
// get the Labels
|
|
lbs.tagMod = SHHMODFrompCXT ( pcxt );
|
|
lbs.addr = *SHpADDRFrompCXT ( pcxt );
|
|
SHpSymlplLabLoc ( &lbs );
|
|
|
|
// check for closest data local, if requested
|
|
if ( ( sop & sopData ) && lbs.tagLoc ) {
|
|
pSym = (SYMPTR) lbs.tagLoc;
|
|
switch (pSym->rectyp) {
|
|
#if defined (ADDR_16) || defined (ADDR_MIXED)
|
|
case S_LDATA16:
|
|
case S_GDATA16:
|
|
doff = GetAddrOff ( lbs.addr ) -
|
|
(CV_uoff32_t)(((DATAPTR16)pSym)->off);
|
|
STRNCPY (lpch, (char FAR *)&((DATAPTR16)pSym)->name[1],
|
|
(BYTE)(*((DATAPTR16)pSym)->name));
|
|
lpch[(BYTE)(*((DATAPTR16)pSym)->name)] = '\0';
|
|
break;
|
|
#endif
|
|
|
|
#if defined (ADDR_32) || defined (ADDR_MIXED) || defined (TARGET32)
|
|
case S_LDATA32:
|
|
case S_GDATA32:
|
|
case S_LTHREAD32:
|
|
case S_GTHREAD32:
|
|
doff = GetAddrOff ( lbs.addr ) -
|
|
(CV_uoff32_t)(((DATAPTR32)pSym)->off);
|
|
_ftcsncpy (lpch, (char FAR *)&((DATAPTR32)pSym)->name[1],
|
|
(BYTE)(*((DATAPTR32)pSym)->name));
|
|
lpch[(BYTE)(*((DATAPTR32)pSym)->name)] = '\0';
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// check for closest label
|
|
if ( !(sop & sopFcn ) && lbs.tagLab ) {
|
|
pSym = (SYMPTR) lbs.tagLab;
|
|
switch (pSym->rectyp) {
|
|
#if defined (ADDR_16) || defined (ADDR_MIXED)
|
|
case S_LABEL16:
|
|
doff = GetAddrOff ( lbs.addr ) -
|
|
(CV_uoff32_t)(((LABELPTR16)pSym)->off) ;
|
|
_ftcsncpy (lpch, (char FAR *)&((LABELPTR16)pSym)->name[1],
|
|
(BYTE)(*((LABELPTR16)pSym)->name));
|
|
lpch[(BYTE)(*((LABELPTR16)pSym)->name)] = '\0';
|
|
break;
|
|
#endif
|
|
|
|
#if defined (ADDR_32) || defined (ADDR_MIXED) || defined (TARGET32)
|
|
case S_LABEL32:
|
|
doff = GetAddrOff ( lbs.addr ) -
|
|
(CV_uoff32_t)(((LABELPTR32)pSym)->off) ;
|
|
_ftcsncpy (lpch, (char FAR *)&((LABELPTR32)pSym)->name[1],
|
|
(BYTE)(*((LABELPTR32)pSym)->name));
|
|
lpch[(BYTE)(*((LABELPTR32)pSym)->name)] = '\0';
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// if the proc name is closer
|
|
if ( lbs.tagProc ) {
|
|
pSym = (SYMPTR) lbs.tagProc;
|
|
switch (pSym->rectyp) {
|
|
#if defined (ADDR_16) || defined (ADDR_MIXED)
|
|
case S_LPROC16:
|
|
case S_GPROC16:
|
|
doffNew = GetAddrOff ( lbs.addr ) -
|
|
(CV_uoff32_t)(((PROCPTR16)pSym)->off);
|
|
if (doffNew <= doff) {
|
|
doff = doffNew;
|
|
_ftcsncpy (lpch, (char FAR *)&((PROCPTR16)pSym)->name[1],
|
|
(BYTE)(*((PROCPTR16)pSym)->name));
|
|
lpch[(BYTE)(*((PROCPTR16)pSym)->name)] = '\0';
|
|
lpodr->cbProlog = ((PROCPTR16)pSym)->DbgStart - 1;
|
|
lpodr->fcd = (((PROCPTR16)pSym)->flags.CV_PFLAG_FAR ) ? fcdFar : fcdNear;
|
|
lpodr->fst = fstSymbol;
|
|
if ( doff < (CV_uoff32_t)((PROCPTR16)pSym)->len ) {
|
|
bAddrInProc = TRUE;
|
|
}
|
|
|
|
}
|
|
break;
|
|
#endif
|
|
#if defined (ADDR_32) || defined (ADDR_MIXED) || defined (TARGET32)
|
|
case S_LPROC32:
|
|
case S_GPROC32:
|
|
doffNew = GetAddrOff ( lbs.addr ) -
|
|
(CV_uoff32_t)(((PROCPTR32)pSym)->off);
|
|
if (doffNew <= doff) {
|
|
doff = doffNew;
|
|
_ftcsncpy (lpch, (char FAR *)&((PROCPTR32)pSym)->name[1],
|
|
(BYTE)(*((PROCPTR32)pSym)->name));
|
|
lpch[(BYTE)(*((PROCPTR32)pSym)->name)] = '\0';
|
|
|
|
// cbProlog is a WORD, so until we change that, we'll
|
|
// have to make sure the prolog is <64K (a safe bet)
|
|
|
|
assert ( ((PROCPTR32)pSym)->DbgStart <= 65535 );
|
|
lpodr->cbProlog = (WORD)(((PROCPTR32)pSym)->DbgStart);
|
|
|
|
lpodr->fcd = (((PROCPTR32)pSym)->flags.CV_PFLAG_FAR ) ? fcdFar : fcdNear;
|
|
lpodr->fst = fstSymbol;
|
|
if (((PROCPTR32)pSym)->flags.CV_PFLAG_NOFPO ) {
|
|
lpodr->fpt = fptPresent;
|
|
}
|
|
if ( doff < (CV_uoff32_t)((PROCPTR32)pSym)->len ) {
|
|
bAddrInProc = TRUE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case S_LPROCMIPS:
|
|
case S_GPROCMIPS:
|
|
doffNew = GetAddrOff ( lbs.addr ) -
|
|
(CV_uoff32_t)(((PROCPTRMIPS)pSym)->off);
|
|
if (doffNew <= doff) {
|
|
doff = doffNew;
|
|
_ftcsncpy (lpch, (char FAR *)&((PROCPTRMIPS)pSym)->name[1],
|
|
(BYTE)(*((PROCPTRMIPS)pSym)->name));
|
|
lpch[(BYTE)(*((PROCPTRMIPS)pSym)->name)] = '\0';
|
|
|
|
// cbProlog is a WORD, so until we change that, we'll
|
|
// have to make sure the prolog is <64K (a safe bet)
|
|
if ( ((PROCPTRMIPS)pSym)->DbgStart == 0 ) {
|
|
lpodr->cbProlog = 0;
|
|
}
|
|
else {
|
|
// TEMPORARY HACK !!!!!!! - sanjays
|
|
assert ( ((PROCPTRMIPS)pSym)->DbgStart - 1 <= 65535 );
|
|
lpodr->cbProlog = (WORD)(((PROCPTRMIPS)pSym)->DbgStart - 1);
|
|
}
|
|
|
|
lpodr->fcd = fcdNear;
|
|
lpodr->fst = fstSymbol;
|
|
|
|
if ( doff < (CV_uoff32_t)((PROCPTRMIPS)pSym)->len ) {
|
|
bAddrInProc = TRUE;
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
if ( !doff ) {
|
|
lpodr->dwDeltaOff = 0; // Exact Match
|
|
return;
|
|
}
|
|
|
|
// Avoid searching the publics if the address we were searching for
|
|
// is in the range of the proc we found.
|
|
if ( bAddrInProc && !(sop & sopData))
|
|
{
|
|
lpodr->dwDeltaOff = doff;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// now check the publics
|
|
|
|
doffNew = PHGetNearestHsym (
|
|
SHpADDRFrompCXT ( pcxt ),
|
|
SHpADDRFrompCXT ( pcxt )->emi,
|
|
&hSym
|
|
);
|
|
|
|
if ( doffNew < doff ) {
|
|
doff = doffNew;
|
|
pSym = (SYMPTR) hSym;
|
|
switch (pSym->rectyp) {
|
|
#if defined (ADDR_16) || defined (ADDR_MIXED)
|
|
case S_GDATA16:
|
|
case S_PUB16:
|
|
_ftcsncpy (lpch, (char FAR *)&((DATAPTR16)pSym)->name[1],
|
|
(BYTE)(*((DATAPTR16)pSym)->name));
|
|
lpch[(BYTE)(*((DATAPTR16)pSym)->name)] = '\0';
|
|
lpodr->fst = fstPublic;
|
|
break;
|
|
#endif
|
|
|
|
#if defined (ADDR_32) || defined (ADDR_MIXED) || defined (TARGET32)
|
|
case S_GDATA32:
|
|
case S_PUB32:
|
|
_ftcsncpy (lpch, (char FAR *)&((DATAPTR32)pSym)->name[1],
|
|
(BYTE)(*((DATAPTR32)pSym)->name));
|
|
lpch[(BYTE)(*((DATAPTR32)pSym)->name)] = '\0';
|
|
lpodr->fst = fstPublic;
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
lpodr->dwDeltaOff = doff;
|
|
return;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
// the next few functions are provided to osdebug via callbacks and
|
|
// should not be called within the CV kernel
|
|
//
|
|
//
|
|
//
|
|
//
|
|
|
|
|
|
/*** SHModelFromCXT
|
|
*
|
|
* Purpose: To fill the supplied buffer with the relevant Change
|
|
* Execution Model record from the symbols section.
|
|
*
|
|
* Input: pcxt - a pointer to the context, address
|
|
* and mdi must be filled in.
|
|
*
|
|
* Output:
|
|
* pch - The Change Execution Model record is copied here.
|
|
* Returns .....
|
|
* True if there is symbol information for the module.
|
|
*
|
|
* Exceptions:
|
|
*
|
|
* Notes: If there is no symbol information for the module, the supplied
|
|
* buffer is not changed and the function returns FALSE.
|
|
*
|
|
*************************************************************************/
|
|
|
|
int PASCAL SHModelFromCXT (
|
|
PCXT pcxt,
|
|
LPW lpwModel,
|
|
SYMPTR FAR * lppMODEL,
|
|
CV_uoff32_t *pobMax
|
|
) {
|
|
static CEXMPTR16 tagOld;
|
|
static CV_uoff32_t obMax;
|
|
static CV_uoff32_t obMin;
|
|
static HEMI emiOld = 0;
|
|
static WORD segOld = 0;
|
|
|
|
LBS lbs;
|
|
ADDR addrT;
|
|
LPMDS lpmds;
|
|
HMOD hmod;
|
|
CB cbSecContrib;
|
|
BOOL fTmp;
|
|
|
|
|
|
// if physical, unfix it up
|
|
if ( !ADDR_IS_LI ( *SHpADDRFrompCXT ( pcxt ) ) ) {
|
|
SYUnFixupAddr ( SHpADDRFrompCXT ( pcxt ) );
|
|
}
|
|
|
|
if ( segOld != (WORD) GetAddrSeg ( *SHpADDRFrompCXT(pcxt) ) ||
|
|
( emiOld != emiAddr ( *SHpADDRFrompCXT(pcxt) ) ) ||
|
|
( GetAddrOff ( *SHpADDRFrompCXT(pcxt) ) >= obMax ) ||
|
|
( GetAddrOff ( *SHpADDRFrompCXT(pcxt) ) < obMin ) ) {
|
|
|
|
if ( !SHHMODFrompCXT ( pcxt ) ) {
|
|
addrT = *SHpADDRFrompCXT ( pcxt );
|
|
MEMSET ( pcxt, 0, sizeof ( CXT ) );
|
|
if ( !SHSetCxtMod ( &addrT, pcxt ) ) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
hmod = (HMOD)SHHGRPFrompCXT( pcxt );
|
|
lpmds = LLLock ( hmod );
|
|
|
|
emiOld = emiAddr ( *SHpADDRFrompCXT(pcxt) );
|
|
fTmp = SHIsAddrInMod (lpmds, &pcxt->addr, &segOld, &obMin, &cbSecContrib);
|
|
obMax = obMin + cbSecContrib + 1;
|
|
LLUnlock( hmod );
|
|
tagOld = NULL;
|
|
|
|
// at some point we may wish to specify only a scope to search for
|
|
// a label. So we may wish to initialize the lbs differently
|
|
|
|
// get the Relevant change model records
|
|
|
|
if ( GetSymbols ((LPMDS)LLLock (lbs.tagMod = SHHMODFrompCXT (pcxt))) ) {
|
|
lbs.addr = *SHpADDRFrompCXT(pcxt);
|
|
SHpSymlplLabLoc ( &lbs );
|
|
if (tagOld = lbs.tagModelMin ) {
|
|
// emsT = (SYMPTR) tagOld;
|
|
// obMin = ((CEXMPTR16)emsT)->off;
|
|
#if defined(TARGMAC68K) || defined(TARGMACPPC)
|
|
if(((SYMPTR)(lbs.tagModelMin))->rectyp == S_CEXMODEL32)
|
|
obMin = ((CEXMPTR32)(lbs.tagModelMin))->off;
|
|
else
|
|
#endif
|
|
|
|
obMin = (lbs.tagModelMin)->off;
|
|
}
|
|
if (lbs.tagModelMax) {
|
|
// emsT = (SYMPTR) lbs.tagModelMax;
|
|
// obMax = ((CEXMPTR16)emsT)->off;
|
|
#if defined(TARGMAC68K) || defined(TARGMACPPC)
|
|
if(((SYMPTR)(lbs.tagModelMax))->rectyp == S_CEXMODEL32)
|
|
obMax = ((CEXMPTR32)(lbs.tagModelMax))->off;
|
|
else
|
|
#endif
|
|
obMax = (lbs.tagModelMax)->off;
|
|
}
|
|
}
|
|
LLUnlock( lbs.tagMod );
|
|
}
|
|
|
|
if( tagOld != NULL ) {
|
|
|
|
// pass on ptr to the SYM
|
|
*lppMODEL = (SYMPTR) tagOld;
|
|
#if defined(TARGMAC68K) || defined(TARGMACPPC)
|
|
if(((SYMPTR)(tagOld))->rectyp == S_CEXMODEL32)
|
|
*lpwModel = ( (CEXMPTR32) *lppMODEL ) -> model;
|
|
else
|
|
#endif
|
|
*lpwModel = ( (CEXMPTR16) *lppMODEL ) -> model;
|
|
if ( *lpwModel != CEXM_MDL_cobol
|
|
&& *lpwModel != CEXM_MDL_pcode32Mac
|
|
&& *lpwModel != CEXM_MDL_pcode32MacNep
|
|
) {
|
|
*lpwModel &= 0xfff0;
|
|
}
|
|
}
|
|
else {
|
|
|
|
// no model record, must be native
|
|
*lppMODEL = NULL;
|
|
*lpwModel = CEXM_MDL_native;
|
|
}
|
|
*pobMax = obMax;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*** SHModelFromAddr
|
|
*
|
|
* Purpose: To fill the supplied buffer with the relevant Change
|
|
* Execution Model record from the symbols section.
|
|
*
|
|
* Input: pcxt - a pointer to an addr,
|
|
*
|
|
* Output:
|
|
* pch - The Change Execution Model record is copied here.
|
|
* Returns .....
|
|
* True if there is symbol information for the module.
|
|
*
|
|
* Exceptions:
|
|
*
|
|
* Notes: If there is no symbol information for the module, the supplied
|
|
* buffer is not changed and the function returns FALSE.
|
|
*
|
|
*************************************************************************/
|
|
|
|
int PASCAL LOADDS SHModelFromAddr (
|
|
LPADDR paddr,
|
|
LPW lpwModel,
|
|
LPB lpbModel,
|
|
CV_uoff32_t FAR *pobMax
|
|
) {
|
|
static CEXMPTR16 tagOld;
|
|
static CV_uoff32_t obMax = 0;
|
|
static CV_uoff32_t obMin = 0;
|
|
static HEMI emiOld = 0;
|
|
static WORD segOld = 0;
|
|
|
|
SYMPTR FAR *lppModel = (SYMPTR FAR *) lpbModel;
|
|
LBS lbs;
|
|
ADDR addr;
|
|
LPMDS lpmds;
|
|
HMOD hmod;
|
|
CXT cxt = {0};
|
|
CB cbSecContrib;
|
|
BOOL fTmp;
|
|
|
|
// if physical, unfix it up
|
|
if ( !ADDR_IS_LI (*paddr) ) SYUnFixupAddr ( paddr );
|
|
|
|
cxt.addr = *paddr;
|
|
cxt.hMod = 0;
|
|
|
|
if ( segOld != (WORD) GetAddrSeg ( *SHpADDRFrompCXT(&cxt) ) ||
|
|
( emiOld != emiAddr ( *SHpADDRFrompCXT(&cxt) ) ) ||
|
|
( GetAddrOff ( *SHpADDRFrompCXT(&cxt) ) >= obMax ) ||
|
|
( GetAddrOff ( *SHpADDRFrompCXT(&cxt) ) < obMin ) ) {
|
|
|
|
if ( !SHHMODFrompCXT ( &cxt ) ) {
|
|
addr = *SHpADDRFrompCXT ( &cxt );
|
|
MEMSET ( &cxt, 0, sizeof ( CXT ) );
|
|
if ( !SHSetCxtMod ( &addr, &cxt ) ) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
hmod = (HMOD)SHHGRPFrompCXT( &cxt );
|
|
lpmds = LLLock ( hmod );
|
|
emiOld = emiAddr ( *SHpADDRFrompCXT(&cxt) );
|
|
fTmp = SHIsAddrInMod ( lpmds, &cxt.addr, &segOld, &obMin, &cbSecContrib);
|
|
assert(fTmp);
|
|
obMax = obMin + cbSecContrib + 1;
|
|
LLUnlock( hmod );
|
|
tagOld = NULL;
|
|
|
|
// at some point we may wish to specify only a scope to search for
|
|
// a label. So we may wish to initialize the lbs differently
|
|
|
|
// get the Relevant change model records
|
|
|
|
if ( GetSymbols ((LPMDS) LLLock (lbs.tagMod = SHHMODFrompCXT (&cxt))) ) {
|
|
lbs.addr = *SHpADDRFrompCXT(&cxt);
|
|
SHpSymlplLabLoc ( &lbs );
|
|
if (tagOld = lbs.tagModelMin ) {
|
|
// emsT = (SYMPTR) tagOld;
|
|
// obMin = ((CEXMPTR16)emsT)->off;
|
|
#if defined(TARGMAC68K) || defined(TARGMACPPC)
|
|
if(((SYMPTR)(lbs.tagModelMin))->rectyp == S_CEXMODEL32)
|
|
obMin = ((CEXMPTR32)(lbs.tagModelMin))->off;
|
|
else
|
|
#endif
|
|
obMin = (lbs.tagModelMin)->off;
|
|
}
|
|
if (lbs.tagModelMax) {
|
|
// emsT = (SYMPTR) lbs.tagModelMax;
|
|
// obMax = ((CEXMPTR16)emsT)->off;
|
|
#if defined(TARGMAC68K) || defined(TARGMACPPC)
|
|
if(((SYMPTR)(lbs.tagModelMax))->rectyp == S_CEXMODEL32)
|
|
obMax = ((CEXMPTR32)(lbs.tagModelMax))->off;
|
|
else
|
|
#endif
|
|
obMax = (lbs.tagModelMax)->off;
|
|
}
|
|
}
|
|
LLUnlock( lbs.tagMod );
|
|
}
|
|
|
|
if( tagOld != NULL ) {
|
|
|
|
// pass on ptr to the SYM
|
|
*lppModel = (SYMPTR) tagOld;
|
|
#if defined(TARGMAC68K) || defined(TARGMACPPC)
|
|
if(((SYMPTR)tagOld)->rectyp == S_CEXMODEL32)
|
|
*lpwModel = ( (CEXMPTR32) *lppModel ) -> model;
|
|
else
|
|
#endif
|
|
*lpwModel = ( (CEXMPTR16) *lppModel ) -> model;
|
|
if ( *lpwModel != CEXM_MDL_cobol
|
|
&& *lpwModel != CEXM_MDL_pcode32Mac
|
|
&& *lpwModel != CEXM_MDL_pcode32MacNep
|
|
) {
|
|
*lpwModel &= 0xfff0;
|
|
}
|
|
}
|
|
else {
|
|
|
|
// no model record, must be native
|
|
*lppModel = NULL;
|
|
*lpwModel = CEXM_MDL_native;
|
|
}
|
|
*pobMax = obMax;
|
|
return TRUE;
|
|
|
|
}
|