home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
sd386v50.zip
/
sd386src.zip
/
SYMBOLS.C
< prev
next >
Wrap
Text File
|
1996-08-26
|
52KB
|
871 lines
/*****************************************************************************/
/* File: IBM INTERNAL USE ONLY */
/* symbols.c */
/* */
/* Description: */
/* Handling of symbols segment generated by the compiler and fixed up by */
/* the linker. */
/* */
/* History: */
/* */
/* 02/08/91 Creation of 32-bit SD86, from 16-bit version. */
/* */
/*...16->32 port. */
/*... */
/*... 02/08/91 100 Philip port to 32 bit. */
/*... 02/08/91 101 Joe port to 32 bit. */
/*... 02/08/91 102 Pratima port to 32 bit. */
/*... 02/08/91 103 Dave port to 32 bit. */
/*... 02/08/91 104 */
/*... 02/08/91 105 Christina port to 32 bit. */
/*... 02/08/91 106 Srinivas port to 32 bit. */
/*... 02/08/91 107 Dave port to 32 bit. */
/*... 02/08/91 108 Dave port to 32 bit. */
/*... 02/08/91 109 */
/*... 02/08/91 110 Srinivas port to 32 bit. */
/*... 02/08/91 111 Christina port to 32 bit. */
/*... 02/08/91 112 Joe port to 32 bit. */
/*... 02/08/91 113 */
/*... 02/08/91 114 */
/*... 02/08/91 115 Srinivas port to 32 bit. */
/*... 02/08/91 116 Joe port to 32 bit. */
/* */
/*...Release 1.00 (Pre-release 1) */
/*... */
/*... 07/09/91 205 srinivas Hooking up of register variables. */
/*... 07/19/91 218 srinivas global variables not being shown properly. */
/*... 09/11/91 237 Srinivas Proper initialization of debug format flags. */
/*... 09/25/91 240 Srinivas recursive PLX based variables. */
/*... 09/25/91 241 Srinivas hanging PLX based variables. */
/*... */
/*...Release 1.00 (Pre-release 107 11/13/91) */
/*... */
/*... 11/21/91 403 Srinivas case sensitivity with structure member names.*/
/*... */
/*...Release 1.00 (Pre-release 1.08 10/10/91) */
/*... */
/*... 02/07/92 512 Srinivas Handle Toronto "C" userdefs. */
/*... ( 512 Backed out by change 813). */
/*... 02/12/92 521 Srinivas Port to C-Set/2. */
/*... */
/*...Release 1.00 (03/03/92) */
/*... */
/*... 03/16/92 605 Srinivas HLL Reg Symbol record not being mapped. */
/*... 03/18/92 606 Srinivas Handle multiple segment numbers in lno table */
/*... due to alloc_text pragma. */
/*... 01/26/93 809 Selwyn HLL Level 2 support. */
/*... 03/03/93 813 Joe Revised types handling for HL03. */
/*... */
/**Includes*******************************************************************/
#include "all.h" /* SD86 include files */
/**Externs********************************************************************/
extern SCOPE ExprScope; /* Set by ParseExpr and findlvar. */
extern uint ExprTid; /* Set by ParseExpr and findlvar */
/* and findsvar. */
extern PtraceBuffer AppPTB; /* Application Ptrace buffer. */
extern CmdParms cmd; /* start command parms. */
SSProc *Qproc; /* Set by Qsymbol() to the SSProc */
/* record containing the symbol. */
/*************************************************************************101*/
/* CopyProcName() 101*/
/* 101*/
/* Description: 101*/
/* copys the procedure name from a scope record into a buffer. 101*/
/* 101*/
/* Parameters: 101*/
/* scope input - ptr to scope record. 101*/
/* buf output - buffer destination of the name. 101*/
/* buflen output - length of the buffer we're stuffing into. 101*/
/* 101*/
/* Return: 101*/
/* buf -> to the buffer. 101*/
/* 101*/
/* Assumptions: 101*/
/* 101*/
/* scope -> a valid scope record. 101*/
/* 101*/
/*************************************************************************101*/
uchar * /*101*/
CopyProcName( void *scope, uchar *buf, uint buflen ) /*101*/
{ /*101*/
uint n; /*101*/
uchar *PtrToProcName; /*101*/
/*101*/
/****************************************************************************/
/* - get a ptr to the name field of the SSProc record. 101*/
/* - get the length of the name and put it in the buffer. 101*/
/* - truncate the name if needed. 101*/
/****************************************************************************/
n = 0; /*101*/
if (scope != NULL) /*107*/
{ /*107*/
BOOL IsMangled;
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
PtrToProcName = &(((SSProc *)scope )->Name[0]);
IsMangled = FALSE;
IsMangled = unmangle( buffer, PtrToProcName );
if( IsMangled == FALSE )
{
n = ((SSProc *)scope)->NameLen;
if( n > buflen-1 )
n = buflen;
memcpy(buf, PtrToProcName, n );
}
else
{
n = strlen(buffer);
if( n > buflen-1 )
n = buflen;
memcpy(buf, buffer, n);
}
}
buf[n] = 0;
return( buf );
}
uint
findsvar(uint mid,varstr vsym )
{
DEBFILE *pdf;
uchar *p, *pend; /* was register. 112*/
uint nested=0;
ULONG len;
int rc; /* string compare return code */
uchar *pname; /* */
pdf = DBFindPdf( mid );
if( !pdf )
goto error;
if( (p = (uchar*) DBSymSeg(mid, &len , pdf)) && len )
{
for( pend = p + len; p < pend; p = (uchar *) NextSSrec(p) )
{
switch( ((SSRec *)p)->RecType ) /*809*/
{
case SSPROC: /*809*/
case SSBEGIN: /*809*/
nested += 1; break;
case SSEND: /*809*/
nested -= 1; break;
case SSVAR: /* static variable case 809*/
{
len = *(USHORT *)vsym; /* length of name in vsym 809*/
pname = ((SSVar *)p)->Name; /* -> to name in SSvar16 record 809*/
if( !nested && len == ((SSVar *)p)->NameLen )
/* the name lengths match then */
{ /* if between "{}" and */
rc = strncmp(pname, vsym+2 , len); /* compare character names 809*/
/* as is */
if (rc && !cmd.CaseSens ) /* mismatch & !case sensitive? */
rc = memicmp(pname, vsym+2 ,len); /* now compare again. 809 403*/
/* with case insenstivty. 403*/
if( rc == 0 ) /* did they match? */
{
ExprTid = ((SSVar *)p)->TypeIndex; /*809*/
/* set expression type id */
return( (uint)(((SSVar *)p)->Offset) ); /*809*/
} /* end of not case sensitive */
}
break; /* end of between "{}" */
}
} } }
error:
return( NULL );
}
uint
findlvar( uint mid, uchar *vsym, uint lno, int sfi, BOOL *pthis )
{
ushort kind=0;
int target;
SSRec *p;
Trec *tp; /* -> type rec in $$type info. */
target = NULL; /* 116*/
p = Qsymbol(mid, lno, sfi, vsym);
if( p == NULL )
{
char this[6];
this[0] = 4;
this[1] = 0;
this[2] = 't';
this[3] = 'h';
this[4] = 'i';
this[5] = 's';
p = Qsymbol( mid, lno, sfi, this );
if(p)
*pthis = TRUE;
}
if(p) /*521*/
{
switch( p->RecType )
{
case SSDEF: /*809*/
{
target = ( (SSDef *)p )->FrameOffset; /*809*/
if( target >= 0 )
SetBit(target,STACKADDRBIT);
kind = ( (SSDef *)p )->TypeIndex; /*809*/
break;
}
case SSVAR: /*809*/
target = ((SSVar *)p) ->Offset; /*809*/
kind = ((SSVar *)p) ->TypeIndex; /*809*/
break;
case SSREG: /*809*/
switch( ((SSReg *)p) ->RegNum )
{ /*809*/
case SSREGBX16: /*605*/
case SSREGBX32: /*605*/
target = (uint)(&AppPTB.EBX) - (uint)(&AppPTB); /*205*/
break; /*205*/
case SSREGSI16: /*605*/
case SSREGSI32: /*605*/
target = (uint)(&AppPTB.ESI) - (uint)(&AppPTB); /*205*/
break; /*205*/
case SSREGDI16: /*605*/
case SSREGDI32: /*605*/
target = (uint)(&AppPTB.EDI) - (uint)(&AppPTB); /*205*/
break; /*205*/
} /*205*/
SetBit(target,REGADDRBIT); /*205*/
kind = ((SSReg *)p) ->TypeIndex; /*809*/
break; /*205*/
case SSUSERDEF: /*809*/
/**********************F******************************************************/
/* This case was added to support PL/X based variables. If we get here, */
/* a typedef record has been found in the symbols area within the context */
/* an SSProc block. In the example consider the Typedef TABLE. */
/* */
/*$$symbols dump: */
/* 105 Proc 5F36 0790 06DE 0000 06DE LECSORT */
/* 105 TypeDef 0562 SORT@ */
/* 105 Defn 0006 0193 @PA00079 */
/* 105 TypeDef 0564 COMMUNAL */
/* 105 TypeDef 0601 GAB */
/* 105 TypeDef 0662 LSEG */
/* 105 TypeDef 0711 NAMEENTRY */
/* 105 TypeDef 0746 PUBLIC */
/* 105 Defn FFFA 0129 RC */
/* 105 TypeDef 0788 TABLE */
/* 105 End */
/* 105 Static 0005:85EE 0193 WORK1@ */
/* 105 Static 0005:85F2 0193 TAB@ */
/* 105 Static 0005:85F6 0130 CNT */
/* 105 Static 0005:85FA 0130 START */
/* 105 Static 0005:85FE 0130 LAST */
/* 105 Static 0005:8602 0130 UPP */
/* 105 Static 0005:8606 0130 DOWN */
/* 105 Static 0005:860A 0193 HOLD@ */
/* 105 Static 0005:860E 0129 NUMINCHAIN */
/* 105 Static 0005:8610 0516 TYPESRT */
/* 105 Static 0005:8612 0517 MODLST */
/* 105 Static 0005:862C 0521 SORTFLAGS */
/* 105 Static 0005:862E 0526 COMMON */
/* */
/*$$types dump: */
/* 788) Ptr : Far Type:789 Name:TAB@ */
/* 789) Array : Bytes:4 Type:INT * */
/* */
/*Here's what we do: */
/* */
/* 1. Get the typeno associated with the typedef record. In this */
/* example "TABLE" has a Typedef = 788. */
/* 2. Get a pointer to this type record in the $$types area. */
/* 3. If the type record (788) is not a Ptr, then we assume that the */
/* variable was declared as "based" but no basing pointer was */
/* specified. In this case, we cannot get a pointer to the storage */
/* that we want to type so we return a NULL target. */
/* 4. if it is a T_PTR then: */
/* - resolve the typeno. In this case 789. */
/* This establishes the type to associate with the based variable. */
/* - Now we have to get a pointer to the storage to be typed. We get */
/* this from the name field of the Ptr record. In this case "TAB@". */
/* - find the basing pointer location. This is the location of */
/* "TAB@". */
/* - The basing pointer location will contain the pointer that */
/* locates the storage, so we dereference it. */
/* 5. establish ExprTid and ExprScope. */
/* 6. return the target or NULL. */
/* */
/*****************************************************************************/
{ /* */
uchar *pname; /* a ptr to the name. */
uchar pubname[256]; /* DBPub() requires Z string. */
uint ptr; /* a pointer holder. */
SSProc *Qprocsave; /* Set by Qsymbol() to the SSProc */
DEBFILE *pdf; /* debug file node. */
BOOL junk;
/* */
kind = ((TD_USERDEF*)p)->TypeIndex; /* establish type of based var 813*/
tp = QbasetypeRec(mid, kind); /* get a ptr to its type rec. */
if( tp && /* if it exists and it's a pointer */
(tp->RecType == T_PTR ) /* then we continue, else we retur813*/
) /* a NULL target. */
{ /* */
kind = ((TD_POINTER*)tp)->TypeIndex; /*813*/
/* */
if (kind < 512) /* if the type is primitive then 241*/
break; /* its a hanging based variable 241*/
/* then we can't do any thing 241*/
pname = (uchar*)&(((TD_POINTER*)tp)->NameLen); /*813*/
/*****************************************************************************/
/* At this point, we have a based variable and we know the name of the */
/* basing pointer. The basing pointer can be anywhere, so we will do a */
/* general search for this guy. We will have to make a recursive call */
/* to findlvar() ( !!eeks ) so we will have to save/restore Qproc,which */
/* is the scope of the based variable, since it gets set by findlvar(). */
/* We look for the basing pointer in the following order: */
/* */
/* 1. local variable or statics/externs declared in scope. */
/* 2. static variables. */
/* 3. public variables. */
/* */
/* Dereference the pointer if we find it. */
/*****************************************************************************/
Qprocsave = Qproc; /* save the -> to scoping rec */
ptr = findlvar(mid, pname, lno, sfi, &junk);
if( ptr == NULL )
{
ptr = findsvar(mid,pname);
if( ptr == NULL )
{
pdf=DBFindPdf(mid);
if( pdf != NULL )
{
USHORT NameLen = *(USHORT *)pname;
strncpy( pubname, pname+2, NameLen );
pubname[NameLen] = '\0';
ptr = DBPub(pubname,pdf);
}
}
}
if(ptr != NULL) /* if we found the symbol, then */
target = DerefPointer(ptr,mid); /* dereference the pointer. 240*/
Qproc = Qprocsave; /* restore the scope of based var. */
} /* */
break; /* typedef handling is done. */
} /* end of blocking for SSTYPEDEF. */
/* */
/*****************************************************************************/
} /* end of switch->rectype */
}
if( target != NULL ) { /* 218*/
ExprTid = kind; /*813*/
ExprScope = Qproc;
}
return( target );
}
/*****************************************************************************/
/* FindScope() */
/* */
/* Description: */
/* Returns a pointer to the SSProc record for the addr argument. As a side */
/* effect the mid and lno are put into the locations specified by the caller*/
/* if symbol information is found for this addr. */
/* */
/* Parameters: */
/* addr address to be scoped. */
/* midlnoptr where the caller wants the mid/lno stuffed. 107*/
/* */
/* Return: */
/* pointer to SSProc. */
/* NULL if no symbol info for this addr */
/* */
/* Assumptions: */
/* */
/* */
/*****************************************************************************/
void *
FindScope( uint addr, uint *midlnoptr ) /*107*/
{
ULONG mid = 0;
ULONG lno = 0;
DEBFILE *pdf; /* debug file pointer */
*midlnoptr='\0'; /* initialize the mid value 107*/
*(midlnoptr+1)='\0'; /* initialize the lno value 107*/
pdf=FindExeOrDllWithAddr( addr); /* find debug file for addr. 101*/
if(pdf == NULL) /* if we can't find the debug file101*/
return(NULL); /* then return all null values. */
/* */
{
LNOTAB *pLnoTabEntry;
mid = DBMapInstAddr(addr, &pLnoTabEntry, pdf);
if(pLnoTabEntry)
lno = pLnoTabEntry->lno;
}
if(mid) /* find mid and lno for this addr */
{
*midlnoptr=mid; /* mid where caller wants it 107*/
*(midlnoptr+1)=lno; /* lno where caller wants it 107*/
return( LocateScope(addr,mid,pdf) ); /* return pointer to SSProc record */
}
return( NULL); /* if no symbols info for this addr */
} /* then return a null pointer */
/*****************************************************************************/
/* LocateScope() */
/* */
/* Description: */
/* This function finds the SSProc record in the symbols area associated */
/* with the argument address and mid. */
/* */
/* Parameters: */
/* addr the address that we want scoped */
/* mid module containing this address */
/* */
/* Return: */
/* p pointer to the SSProc record */
/* */
/* */
/* */
/*****************************************************************************/
void *
LocateScope( uint addr, uint mid , DEBFILE *pdf)
{
uchar *p; /* pointer to an SSProc record */
uchar *pend; /* pointer to end of symbols area */
ULONG len = 0; /* the size of the symbols area */
MODULE *mptr; /* -> to module for mid parameter.101*/
ULONG ProcStartAddr; /* start of procedure in module. 101*/
ULONG ProcEndAddr; /* end of procedure in module. 101*/
/* looking at proper symbols recs 606*/
/* for a given segment 606*/
ULONG SegFlatAddr = 0;
USHORT SegNum;
/*
DBSYMSEG returns a pointer and length for the local symbols associated with
the mid argument.
*/
p = ( uchar * )DBSymSeg(mid,&len,pdf);
if( p == NULL || len == 0 )
return( NULL );
mptr = GetPtrToModule( mid ,pdf );
switch( mptr->DbgFormatFlags.Syms )
{
case TYPE104_C211:
case TYPE104_C600:
/**************************************************************************/
/* */
/* C211 symbol records do not have an SSCHGDEF record. So we need */
/* to initialize SegFlatAddr based on the single csect record that */
/* the linker generates. */
/* */
/**************************************************************************/
if(mptr->pCsects)
SegFlatAddr = mptr->pCsects->SegFlatAddr;
goto caseTYPE104_C600;
caseTYPE104_C600:
case TYPE104_HL01:
case TYPE104_HL02:
case TYPE104_HL03:
case TYPE104_HL04:
case TYPE104_CL386:
for( pend = p + len; p < pend; p = (uchar *)NextSSrec(p) )
{
if( ((SSRec *)p)->RecType == SSCHGDEF)
{
SegNum = ((SSChgDef *)p)->SegNum;
SegFlatAddr = GetLoadAddr( pdf->mte, SegNum );
}
if( ((SSRec *)p)->RecType == SSPROC )
{
ProcStartAddr = SegFlatAddr + ((SSProc *)p)->ProcOffset;
ProcEndAddr = ProcStartAddr + ( (SSProc *)p )->ProcLen;
if ( addr >= ProcStartAddr && addr < ProcEndAddr )
return( p );
}
}
break;
}
return(NULL);
} /* end of LocateScope function */
/*****************************************************************************/
/* Qsymbol() */
/* */
/* Description: */
/* This function finds a pointer to the SSdef , SSvar, or SSreg record */
/* in the symbols area for a given (mid,lno) context. */
/* */
/* Parameters: */
/* mid module id containing the lno. */
/* lno the context of the symbol. */
/* vsym a pointer to the symbol name. First byte is name length. */
/* */
/* Return: */
/* Qrec a pointer to the SSdef, SSvar, or SSreg record in symbol area. */
/* */
/* */
/* */
/*****************************************************************************/
SSRec *Qsymbol( uint mid, uint lno, int sfi, uchar *vsym )
{
ushort nest; /* depth of left braces "{" */
ushort exclude; /* excludes certain recs inside "{}" */
int disp; /* offset from proc or scope begin */
uchar *p; /* pointer to a symbol record */
uchar *pend; /* pointer to end of symbol area */
uchar *Qrec; /* pointer to the sym rec we want */
ULONG len; /* the span of lno */
uint addr; /* address of lno 101*/
uint type; /* symbol record type */
DEBFILE *pdf; /* -> debug file */
MODULE *mptr; /* -> to module for mid parameter.101*/
uint ProcStartAddr; /* start of procedure in module. 101*/
uint ProcEndAddr; /* end of procedure in module. 101*/
uint BlockStartAddr; /* start of {} block. 101*/
SSRec *PtrToNextSymRec; /* look ahead pointer to next sym.112*/
uchar SkipNextBeginRec; /* skip begin following proc. 112*/
/* looking at proper symbols recs 606*/
/* for a given segment 606*/
ULONG SegFlatAddr;
USHORT SegNum;
pdf=DBFindPdf(mid); /* find a debug file for this mid */
addr=DBMapLno(mid, lno, sfi, &len, pdf );
if( addr == NULL ) /* if not an executable let's try */
addr=DBMapNonExLine(mid, lno, sfi, pdf); /* to map it to a non executable. */
/* */
p = (UCHAR*) DBSymSeg(mid, &len, pdf);
if( (mid == 0 ) ||
(addr == NULL ) ||
(p == NULL ) ||
(len == 0 )
)
return( NULL );
/*****************************************************************************/
/* The first thing we want to do is get to the procedure record that scopes */
/* this symbol. So we get a pointer to the SSProc record that contains this */
/* offset. Note that this code assumes we will always find a proc. */
/*****************************************************************************/
mptr = GetPtrToModule( mid ,pdf );
Qproc = NULL;
pend = NULL; /* initialise pend to null 218*/
switch( mptr->DbgFormatFlags.Syms )
{
case TYPE104_C211: /*809 237*/
case TYPE104_C600: /*809 237*/
/**************************************************************************/
/* */
/* C211 symbol records do not have an SSCHGDEF record. So we need */
/* to initialize SegFlatAddr based on the single csect record that */
/* the linker generates. */
/* */
/**************************************************************************/
if(mptr->pCsects)
SegFlatAddr = mptr->pCsects->SegFlatAddr;
for( pend = p + len; p < pend; p = (uchar *) NextSSrec(p) )
{
if( ((SSRec *)p)->RecType == SSCHGDEF)
{
SegNum = ((SSChgDef *)p)->SegNum;
SegFlatAddr = GetLoadAddr( pdf->mte, SegNum );
}
if( ((SSRec *)p)->RecType == SSPROC) /*809*/
{
ProcStartAddr = SegFlatAddr + ((SSProc *)p)->ProcOffset;
ProcEndAddr = ProcStartAddr + ( (SSProc *)p )->ProcLen;
if ( addr >= ProcStartAddr && addr < ProcEndAddr )
break;
}
}
break;
case TYPE104_HL01: /*809 237*/
case TYPE104_HL02: /*809 237*/
case TYPE104_HL03: /*809 237*/
case TYPE104_HL04:
case TYPE104_CL386: /*809 237*/
for( pend = p + len; p < pend; p = (uchar *)NextSSrec(p) )
{
ULONG SegFlatAddr;
USHORT SegNum;
if( ((SSRec *)p)->RecType == SSCHGDEF)
{
SegNum = ((SSChgDef *)p)->SegNum;
SegFlatAddr = GetLoadAddr( pdf->mte, SegNum );
}
if( ((SSRec *)p)->RecType == SSPROC ) /*809*/
{
ProcStartAddr = SegFlatAddr + ((SSProc *)p)->ProcOffset;
ProcEndAddr = ProcStartAddr + ( (SSProc *)p )->ProcLen; /*809*/
if ( addr >= ProcStartAddr && addr < ProcEndAddr )
break;
}
}
break;
}
Qproc = (SSProc *) p; /* save a pointer to the proc rec. */
/*****************************************************************************/
/* At this point, p locates the SSProc record that scopes this symbol. */
/* */
/* The following "for" loop reads and processes symbol records. The primary */
/* controls are "nest" and "exclude". The "nest" counter counts the level of*/
/* nesting of {} blocks. When nest = 0, we've finished scanning the proc. */
/* The "exclude" counter counts the level of {} blocks excluded from the */
/* search. A block is excluded if its scope does not include the "off" */
/* variable. */
/* */
/* in scope: out of scope: */
/* */
/* off--> */
/* { { { */
/* */
/* off---> */
/* */
/* } } } */
/* off---> */
/* */
/* Logic Overview: */
/* */
/* For the range of symbol records in this proc: */
/* Switch on symbol record type: */
/* Begin: */
/* nest += 1: */
/* if "off" out of scope of {}, exclude += 1: */
/* */
/* End: */
/* nest -= 1; */
/* if exclude > 0, then exclude -= 1: */
/* */
/* Variable: */
/* if !exclude, then look for the symbol in this {}: */
/* scan to end of {} and continue looking for shadows. */
/* */
/* done when nest == 0 */
/* */
/* All "{}" blocks must be searched to resolve possible shadowed variables. */
/* Blocks "{}" that are beyond "off" are obviously out of scope. */
/* */
/* */
/*****************************************************************************/
Qrec = NULL; /* 112*/
SkipNextBeginRec = FALSE; /* 112*/
for( nest = 0, /* scan symbol records. 218*/
exclude = 0; /* 112*/
p < pend ; /* 218*/
p = (uchar *) NextSSrec(p) /* bump to next symbol record. 112*/
) /* 112*/
{ /* 112*/
/* 112*/
type =((SSRec *)p)->RecType; /* define symbol record type. 809 112*/
switch( type ) /* 112*/
{ /* 112*/
/**************************************************************************/
/* We compute a displacement and a length to be used for determining 112*/
/* exclusion of scoping blocks. If we have a begin record immediately 112*/
/* following a proc, then we use the disp and len of the containing 112*/
/* procedure instead of computing values from the begin record. 112*/
/* 112*/
/**************************************************************************/
case SSPROC: /*112*/
PtrToNextSymRec = NextSSrec(p); /*112*/
if ( PtrToNextSymRec->RecType == SSBEGIN ) /*112*/
SkipNextBeginRec = TRUE; /*112*/
{
CSECT *pCsect;
ULONG SegFlatAddr;
pCsect = GetCsectWithAddr( mptr, addr );
SegFlatAddr = pCsect->SegFlatAddr;
BlockStartAddr = SegFlatAddr + ((SSProc *)p)->ProcOffset;
}
disp = addr - BlockStartAddr; /*112*/
len = ((SSProc *)p)->ProcLen; /*809 112*/
goto EXCLUDE; /*112*/
/*112*/
case SSBEGIN: /*112*/
if( SkipNextBeginRec == TRUE ) /*112*/
{ /*112*/
SkipNextBeginRec = FALSE; /*112*/
goto EXCLUDE; /*112*/
} /*112*/
else /*112*/
{ /*112*/
CSECT *pCsect;
ULONG SegFlatAddr;
pCsect = GetCsectWithAddr( mptr, addr );
SegFlatAddr = pCsect->SegFlatAddr;
BlockStartAddr = SegFlatAddr + ((SSBegin *)p)->BlockOffset;
disp = addr - BlockStartAddr; /*112*/
len = ((SSBegin *)p)->BlockLen; /*112*/
goto EXCLUDE; /*112*/
} /*112*/
EXCLUDE:
if( exclude || /* if current records are out of */
(disp < 0) || /* scope or we are starting a {} */
disp >= (int)len /* that is out of scope, then bump */
) /* the exclude flag. */
exclude += 1; /* */
nest += 1; /* bump the nesting level. */
break; /* */
/* */
case SSEND: /* 101*/
/* end scope record "}". */
if( exclude ) /* */
exclude -= 1; /* if out of scope back up a level. */
nest -= 1; /* back up a level of nesting. */
break; /* */
/* */
default: /* all records between "{}". */
if( exclude == 0 ) /* if out of scope, don't consider. */
{ /* */
uchar *q; /* */
p = findsym(p,&Qrec,vsym); /* look for symbol within "{}". */
if( Qrec!=NULL ) /* if we find it in this "{}",then */
for(;;) /* scan to the next "{" or "}" and */
{ /* continue looking for shadows. */
q = (uchar *) NextSSrec(p); /* */
if( *(q+1)==SSBEGIN || /* 101*/
*(q+1)==SSEND ) /* 101*/
break; /* */
p = q; /* */
} /* */
} /* */
break; /* */
} /* end switch of symbol record type */
if ( nest <= 0 ) /* if out of "{}" then break out 218*/
break; /* of for loop 218*/
} /* end scan records in procedure */
return( (SSRec *) Qrec ); /* return ptr to symbol rec in 809*/
} /* $$symbols area. */
/*****************************************************************************/
/* findsym() */
/* */
/* Description: */
/* */
/* Find a variable in the $$symbol segment. */
/* */
/* Parameters: */
/* */
/* p input - -> the initial symbol record. */
/* Qrec output - -> where to put the pointer to the found symbol rec.*/
/* NULL if no find. */
/* vsym input - -> to the symbol name. */
/* */
/* Return: */
/* */
/* p pointer to record or last record before a Begin/End record. */
/* */
/* Assumptions: */
/* */
/* p DOES NOT point to an SSBEGIN or SSEND record on input. */
/* */
/*****************************************************************************/
#define SSDEFHEADERSIZE 9
#define SSREGHEADERSIZE 6
#define SSUSERDEFHEADERSIZE 5
#define SSVARHEADERSIZE 12
uchar *findsym( uchar *p, uchar **Qrec, uchar *vsym )
{ /* */
uint len1; /* length of a symbol record. */
uint len2; /* length of a symbol record. */
uchar *q= NULL; /* a holder for the symbol rec ptr521*/
uint type; /* the type of the symbol record. */
uchar *cp; /* char ptr into symbol record. */
int rc; /* compare return code. */
uchar *cpsym; /* char ptr into vsym. */
/*****************************************************************************/
/* We will scan the symbol segment until we find a match or we run into a */
/* begin/end record. We return a pointer to the record containing the match */
/* or to the last record before we encountered a begin/end record. */
/* */
/*****************************************************************************/
for( ;; )
{
cp = p;
type = *(cp+2); /*809*/
switch( type )
{
case SSDEF:
cp += SSDEFHEADERSIZE; /*809*/
break;
case SSREG:
cp += SSREGHEADERSIZE; /*809*/
break;
case SSUSERDEF:
cp += SSUSERDEFHEADERSIZE; /*809*/
break;
case SSVAR:
cp += SSVARHEADERSIZE; /*809*/
break;
case SSBEGIN:
case SSEND:
return(q);
}
/*****************************************************************************/
/* At this point, we have a ptr to the name in a symbol record. We start to */
/* compare. If lengths do not match, then no need to proceed. */
/* */
/*****************************************************************************/
len1 = *(ushort*)cp; /* get name length in symbol rec. */
cp += 2; /*809*/
cpsym = vsym; /* set pointer to len byte in vsym. */
len2 = *(USHORT*)cpsym; /* if lenghts match, then proceed.813*/
cpsym += 2; /* 813*/
if( len1 == len2 ) /* if lenghts match, then proceed.813*/
{ /* */
if ( cmd.CaseSens == TRUE ) /* perform case sensitive or */
rc = strncmp(cpsym,cp,len1); /* insensitive compare. */
else /* */
rc = strnicmp(cpsym,cp,len1); /* */
if( rc == 0 ) /* if we found a match, give the */
{ /* pointer to the caller and */
*Qrec = p; /* return. */
return(p); /* */
} /* */
} /* */
q = p; /* hold ptr to symbol rec. may need. */
p = (uchar *) NextSSrec(p); /* bump to next symbol record. */
} /* */
} /* */