📄 symbols.c
字号:
pNameTemp = szAccumulatedName;
// symbol-name:type-identifier type-number =
nLen = StrLenUpToWhiteChar(pNameTemp,":");
if((pTypeDefIncluded = PICE_strchr(pNameTemp,'=')) && pNameTemp[nLen+1]=='G')
{
DPRINT((0,"FindTypeDefinitionForCombinedTypes(): symbol includes type definition (%s)\n",pNameTemp));
pTypeNumber = pNameTemp+nLen+1;
if((ulCurrentTypeNumber = ExtractTypeNumber(pTypeNumber)) )
{
DPRINT((0,"FindTypeDefinitionForCombinedTypes(): type-number %x\n",ulCurrentTypeNumber));
if(ulCurrentTypeNumber == ulTypeNumber)
{
DPRINT((0,"FindTypeDefinitionForCombinedTypes(): typenumber %x matches!\n",ulCurrentTypeNumber));
return pNameTemp;
}
}
}
*szAccumulatedName = 0;
}
}
break;
}
pStab++;
}
return NULL;
}
//*************************************************************************
// FindTypeDefinition()
//
//*************************************************************************
LPSTR FindTypeDefinition(PICE_SYMBOLFILE_HEADER* pSymbols,ULONG ulTypeNumber,ULONG ulFileNumber)
{
ULONG i;
PSTAB_ENTRY pStab;
LPSTR pStr,pName,pTypeString;
int nStabLen;
int nOffset=0,nNextOffset=0,strLen;
static char szAccumulatedName[2048];
ULONG ulCurrentTypeNumber,ulCurrentFileNumber=0;
LPSTR pTypeSymbol;
static char szCurrentPath[256];
ENTER_FUNC();
DPRINT((0,"FindTypeDefinition(%u,%u)\n",ulTypeNumber,ulFileNumber));
*szAccumulatedName = 0;
pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
nStabLen = pSymbols->ulSizeOfStabs;
pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
{
pName = &pStr[pStab->n_strx + nOffset];
switch(pStab->n_type)
{
case N_UNDF:
nOffset += nNextOffset;
nNextOffset = pStab->n_value;
break;
case N_SO:
if((strLen = PICE_strlen(pName)))
{
if(pName[strLen-1]!='/')
{
ulCurrentFileNumber++;
if(PICE_strlen(szCurrentPath))
{
PICE_strcat(szCurrentPath,pName);
DPRINT((0,"FindTypeDefinition()1: cha %s, %u\n",szCurrentPath, ulCurrentFileNumber));
}
else
{
DPRINT((0,"FindTypeDefinition(): cha %s, %u\n",pName, ulCurrentFileNumber));
}
}
else
PICE_strcpy(szCurrentPath,pName);
}
else
{
szCurrentPath[0]=0;
}
break;
case N_LSYM:
// stab has no value -> must be type definition
//ei File number count is not reliable
if(pStab->n_value == 0 /*&& ulCurrentFileNumber==ulFileNumber*/)
{
DPRINT((0,"FindTypeDefinition(): pre type definition %s\n",pName));
// handle multi-line symbols
if(strrchr(pName,'\\'))
{
if(PICE_strlen(szAccumulatedName))
{
PICE_strcat(szAccumulatedName,pName);
DPRINT((0,"FindTypeDefinition(): [1] accum. %s\n",szAccumulatedName));
}
else
{
PICE_strcpy(szAccumulatedName,pName);
DPRINT((0,"FindTypeDefinition(): [2] accum. %s\n",szAccumulatedName));
}
szAccumulatedName[PICE_strlen(szAccumulatedName)-1]=0;
}
else
{
DPRINT((0,"FindTypeDefinition(): [3] accum. %s, pname: %s\n",szAccumulatedName, pName));
if(PICE_strlen(szAccumulatedName)==0)
{
PICE_strcpy(szAccumulatedName,pName);
}
else
{
PICE_strcat(szAccumulatedName,pName);
}
pTypeString = szAccumulatedName;
pTypeSymbol = PICE_strchr(pTypeString,':');
if(pTypeSymbol && (*(pTypeSymbol+1)=='t' || *(pTypeSymbol+1)=='T'))
{
// parse it
ulCurrentTypeNumber = ExtractTypeNumber(pTypeString);
DPRINT((0,"FindTypeDefinition(): ulCurrType: %u, LSYM is type %s\n",ulCurrentTypeNumber,pName));
if(ulCurrentTypeNumber == ulTypeNumber)
{
DPRINT((0,"FindTypeDefinition(): type definition %s\n",pTypeString));
return pTypeString;
}
}
*szAccumulatedName=0;
}
}
break;
}
pStab++;
}
return FindTypeDefinitionForCombinedTypes(pSymbols,ulTypeNumber,ulFileNumber);
}
//*************************************************************************
// TruncateString()
//
//*************************************************************************
LPSTR TruncateString(LPSTR p,char c)
{
static char temp[1024];
LPSTR pTemp;
pTemp = temp;
while(*p!=0 && *p!=c)
*pTemp++ = *p++;
*pTemp = 0;
return temp;
}
//*************************************************************************
// FindLocalsByAddress()
//
// find all locals for a given address by first looking up the function
// and then it's locals
//*************************************************************************
PLOCAL_VARIABLE FindLocalsByAddress(ULONG addr)
{
ULONG i;
PSTAB_ENTRY pStab;
LPSTR pStr,pName;
int nStabLen;
int nOffset=0,nNextOffset=0;
PICE_SYMBOLFILE_HEADER* pSymbols;
static char szCurrentFunction[256];
static char szCurrentPath[256];
LPSTR pFunctionName;
ULONG start,end,strLen;
ULONG ulTypeNumber,ulCurrentFileNumber=0;
LPSTR pTypedef;
ULONG ulNumLocalVars=0;
DPRINT((0,"FindLocalsByAddress()\n"));
pFunctionName = FindFunctionByAddress(addr,&start,&end);
DPRINT((0,"FindLocalsByAddress(): pFunctionName = %s\n",pFunctionName));
if(pFunctionName)
{
pSymbols = FindModuleSymbols(addr);
if(pSymbols)
{
pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
nStabLen = pSymbols->ulSizeOfStabs;
pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
{
pName = &pStr[pStab->n_strx + nOffset];
DPRINT((0,"FindLocalsByAddress(): %x %x %x %x %x\n",
pStab->n_strx,
pStab->n_type,
pStab->n_other,
pStab->n_desc,
pStab->n_value));
switch(pStab->n_type)
{
case N_UNDF:
nOffset += nNextOffset;
nNextOffset = pStab->n_value;
break;
case N_SO:
if((strLen = PICE_strlen(pName)))
{
if(pName[strLen-1]!='/')
{
ulCurrentFileNumber++;
if(PICE_strlen(szCurrentPath))
{
PICE_strcat(szCurrentPath,pName);
DPRINT((0,"changing source file1 %s, %u\n",szCurrentPath,ulCurrentFileNumber));
}
else
{
DPRINT((0,"changing source file %s, %u\n",pName,ulCurrentFileNumber));
}
}
else
PICE_strcpy(szCurrentPath,pName);
}
else
{
szCurrentPath[0]=0;
}
break;
case N_LSYM:
// if we're in the function we're looking for
if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
{
DPRINT((0,"local variable1 %.8X %.8X %.8X %.8X %.8X %s\n",pStab->n_strx,pStab->n_type,pStab->n_other,pStab->n_desc,pStab->n_value,pName));
ulTypeNumber = ExtractTypeNumber(pName);
DPRINT((0,"type number = %u\n",ulTypeNumber));
if((pTypedef = FindTypeDefinition(pSymbols,ulTypeNumber,ulCurrentFileNumber)))
{
DPRINT((0,"pTypedef: %x\n", pTypedef));
PICE_strcpy(local_vars[ulNumLocalVars].type_name,TruncateString(pTypedef,':'));
PICE_strcpy(local_vars[ulNumLocalVars].name,TruncateString(pName,':'));
local_vars[ulNumLocalVars].value = (CurrentEBP+pStab->n_value);
local_vars[ulNumLocalVars].offset = pStab->n_value;
local_vars[ulNumLocalVars].line = pStab->n_desc;
local_vars[ulNumLocalVars].bRegister = FALSE;
ulNumLocalVars++;
}
}
break;
case N_PSYM:
// if we're in the function we're looking for
if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
{
DPRINT((0,"parameter variable %.8X %.8X %.8X %.8X %.8X %s\n",pStab->n_strx,pStab->n_type,pStab->n_other,pStab->n_desc,pStab->n_value,pName));
ulTypeNumber = ExtractTypeNumber(pName);
DPRINT((0,"type number = %x\n",ulTypeNumber));
if((pTypedef = FindTypeDefinition(pSymbols,ulTypeNumber,ulCurrentFileNumber)))
{
PICE_strcpy(local_vars[ulNumLocalVars].type_name,TruncateString(pTypedef,':'));
PICE_strcpy(local_vars[ulNumLocalVars].name,TruncateString(pName,':'));
local_vars[ulNumLocalVars].value = (CurrentEBP+pStab->n_value);
local_vars[ulNumLocalVars].offset = pStab->n_value;
ulNumLocalVars++;
}
}
break;
case N_RSYM:
// if we're in the function we're looking for
if(szCurrentFunction[0] && PICE_fncmp(szCurrentFunction,pFunctionName)==0)
{
DPRINT((0,"local variable2 %.8X %.8X %.8X %.8X %.8X %s\n",pStab->n_strx,pStab->n_type,pStab->n_other,pStab->n_desc,pStab->n_value,pName));
ulTypeNumber = ExtractTypeNumber(pName);
DPRINT((0,"type number = %x\n",ulTypeNumber));
if((pTypedef = FindTypeDefinition(pSymbols,ulTypeNumber,ulCurrentFileNumber)))
{
PICE_strcpy(local_vars[ulNumLocalVars].type_name,TruncateString(pTypedef,':'));
PICE_strcpy(local_vars[ulNumLocalVars].name,TruncateString(pName,':'));
local_vars[ulNumLocalVars].value = (LocalRegs[pStab->n_value]);
local_vars[ulNumLocalVars].offset = pStab->n_value;
local_vars[ulNumLocalVars].line = pStab->n_desc;
local_vars[ulNumLocalVars].bRegister = TRUE;
ulNumLocalVars++;
}
}
break;
case N_FUN:
if(PICE_strlen(pName))
{
ULONG len;
len=StrLenUpToWhiteChar(pName,":");
PICE_strncpy(szCurrentFunction,pName,len);
szCurrentFunction[len]=0;
DPRINT((0,"function %s\n",szCurrentFunction));
}
else
{
DPRINT((0,"END of function %s\n",szCurrentFunction));
szCurrentFunction[0]=0;
if(ulNumLocalVars)
{
*local_vars[ulNumLocalVars].name = 0;
return local_vars;
}
}
break;
}
pStab++;
}
}
}
return NULL;
}
//*************************************************************************
// FindSourceLineForAddress()
//
//*************************************************************************
LPSTR FindSourceLineForAddress(ULONG addr,PULONG pulLineNumber,LPSTR* ppSrcStart,LPSTR* ppSrcEnd,LPSTR* ppFilename)
{
ULONG i; // index for walking through STABS
PSTAB_ENTRY pStab; // pointer to STABS
LPSTR pStr,pName; // pointer to STAB strings and current STAB string
int nStabLen; // length of STAB section in bytes
int nOffset=0,nNextOffset=0; // offset and next offset in string table
PICE_SYMBOLFILE_HEADER* pSymbols; // pointer to module's STAB symbol table
static char szCurrentFunction[256];
static char szCurrentPath[256];
static char szWantedPath[256];
LPSTR pFunctionName; // name of function that brackets the current address
ULONG start,end,strLen,ulMinValue=0xFFFFFFFF;
LPSTR pSrcLine=NULL;
BOOLEAN bFirstOccurence = TRUE;
// lookup the functions name and start-end (external symbols)
pFunctionName = FindFunctionByAddress(addr,&start,&end);
DPRINT((0,"FindSourceLineForAddress: for function: %s\n", pFunctionName));
if(pFunctionName)
{
// lookup the modules symbol table (STABS)
pSymbols = FindModuleSymbols(addr);
DPRINT((0,"FindSourceLineForAddress: pSymbols %x\n", pSymbols));
if(pSymbols)
{
DPRINT((0,"FindSourceLineForAddress: pSymbols->ulNumberOfSrcFiles %x\n", pSymbols->ulNumberOfSrcFiles));
// no source files so we don't need to lookup anything
if(!pSymbols->ulNumberOfSrcFiles)
return NULL;
// prepare STABS access
pStab = (PSTAB_ENTRY )((ULONG)pSymbols + pSymbols->ulOffsetToStabs);
nStabLen = pSymbols->ulSizeOfStabs;
pStr = (LPSTR)((ULONG)pSymbols + pSymbols->ulOffsetToStabsStrings);
// walk over all STABS
for(i=0;i<(nStabLen/sizeof(STAB_ENTRY));i++)
{
// the name string corresponding to the STAB
pName = &pStr[pStab->n_strx + nOffset];
// switch STAB type
switch(pStab->n_type)
{
// change offset of name strings
case N_UNDF:
nOffset += nNextOffset;
nNextOffset = pStab->n_value;
break;
// source file change
case N_SO:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -