📄 symbols.c
字号:
ENTER_FUNC(); DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "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 = strlen(pName))) { if(pName[strLen-1]!='/') { ulCurrentFileNumber++; if(strlen(szCurrentPath)) { strcat(szCurrentPath,pName); DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "changing source file %s\n", szCurrentPath); } else { DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "changing source file %s\n", pName); } } else PICE_strcpy(szCurrentPath,pName); } else { szCurrentPath[0]=0; } break; case N_LSYM: // stab has no value -> must be type definition if(pStab->n_value == 0 && ulCurrentFileNumber==ulFileNumber) { DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "pre type definition %s\n", pName); // handle multi-line symbols if(strrchr(pName,'\\')) { if(strlen(szAccumulatedName)) { strcat(szAccumulatedName,pName); DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "[1] accum. %s\n", szAccumulatedName); } else { PICE_strcpy(szAccumulatedName,pName); DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "[2] accum. %s\n", szAccumulatedName); } szAccumulatedName[strlen(szAccumulatedName)-1]=0; } else { DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "[3] accum. %s\n", szAccumulatedName); if(strlen(szAccumulatedName)==0) { PICE_strcpy(szAccumulatedName,pName); } else { strcat(szAccumulatedName,pName); } pTypeString = szAccumulatedName; pTypeSymbol = PICE_strchr(pTypeString,':'); if(pTypeSymbol && (*(pTypeSymbol+1)=='t' || *(pTypeSymbol+1)=='T')) { DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "LSYM is type %s\n", pName); // parse it ulCurrentTypeNumber = ExtractTypeNumber(pTypeString); if(ulCurrentTypeNumber == ulTypeNumber) { DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "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; ENTER_FUNC(); pFunctionName = FindFunctionByAddress(addr,&start,&end); DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "pFunctionName = %s\n", pFunctionName); if(pFunctionName) { pSymbols = FindSymbolTableForModule(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(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "%08lX %x %x %x %08lX\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 = strlen(pName))) { if(pName[strLen-1]!='/') { ulCurrentFileNumber++; if(strlen(szCurrentPath)) { strcat(szCurrentPath,pName); DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "changing source file %s\n", szCurrentPath); } else { DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "changing source file %s\n", pName); } } 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] && strcmp(szCurrentFunction,pFunctionName)==0) { DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "local variable %08lX %.8X %.8X %.8X %08lX %s\n", pStab->n_strx, pStab->n_type, pStab->n_other, pStab->n_desc, pStab->n_value, pName); ulTypeNumber = ExtractTypeNumber(pName); DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "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 = 0; 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] && strcmp(szCurrentFunction,pFunctionName)==0) { DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "parameter variable %08lX %08X %08X %08X %08lX %s\n", pStab->n_strx, pStab->n_type, pStab->n_other, pStab->n_desc, pStab->n_value, pName); ulTypeNumber = ExtractTypeNumber(pName); DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "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 = 0; 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] && strcmp(szCurrentFunction,pFunctionName)==0) { DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "local variable %08lX %08X %08X %08X %08lX %s\n", pStab->n_strx, pStab->n_type, pStab->n_other, pStab->n_desc, pStab->n_value, pName); ulTypeNumber = ExtractTypeNumber(pName); DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "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 = 0; 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(strlen(pName)) { ULONG len; len=StrLenUpToWhiteChar(pName, ":"); strncpy(szCurrentFunction,pName,len); szCurrentFunction[len]=0; DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "function %s\n", szCurrentFunction); } else { DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "END of function %s\n", szCurrentFunction); szCurrentFunction[0]=0; if(ulNumLocalVars) { *local_vars[ulNumLocalVars].name = 0; return local_vars; } } break; } pStab++; } } } LEAVE_FUNC(); 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); if(pFunctionName) { // lookup the modules symbol table (STABS) pSymbols = FindSymbolTableForModule(addr); if(pSymbols) { // 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: DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "changing source file %s\n", pName); // if filename has a length record it if((strLen = strlen(pName))) { PICE_strcpy(szCurrentPath,pName); } // else empty filename else { szCurrentPath[0]=0; } break; // sub-source file change case N_SOL: DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "changing sub source file %s\n", pName); // if filename has a length record it if((strLen = strlen(pName))) { PICE_strcpy(szCurrentPath,pName); } // else empty filename else { szCurrentPath[0]=0; } break; // line number case N_SLINE: // if we're in the function we're looking for if(szCurrentFunction[0] && strcmp(szCurrentFunction,pFunctionName)==0) { //DPRINT(PICE_DEBUG, DBT_SYMBOLS, DBL_INFO, "code source line number #%u for addr. %x (function @ %x) ulMinValue = %x ulDelta = %x\n", pStab->n_desc,start+pStab->n_value,start,ulMinValue,(addr-(start+pStab->n_value))); if(bFirstOccurence) { PICE_strcpy(szWa
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -