📄 profiler.c
字号:
}
}
}
KCALLPROFOFF(74);
return TRUE;
}
#endif // CELOG
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// The following functions are used for GetThreadName.
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Return values from GetModulePointer
#define MODULEPOINTER_ERROR 0
#define MODULEPOINTER_NK 1
#define MODULEPOINTER_DLL 2
#define MODULEPOINTER_PROC 4
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static DWORD
GetModulePointer(
PTHREAD pth,
unsigned int pc,
DWORD* dwResult
)
{
if (!dwResult) {
return MODULEPOINTER_ERROR;
}
*dwResult = (DWORD) NULL;
if (pc & 0x80000000) {
//
// NK.EXE
//
return MODULEPOINTER_NK;
} else if (pc > (DWORD) DllLoadBase && pc < 0x02000000) {
//
// It's a DLL address
//
PMODULE pModMax = NULL, pModTrav = NULL;
DWORD dwMax = 0;
//
// Scan the modules list looking for a module with the highest base
// pointer that's less than the PC
//
pModTrav = pModList;
while (pModTrav) {
DWORD dwBase = ZeroPtr(pModTrav->BasePtr);
if (dwBase > dwMax && dwBase < pc) {
dwMax = dwBase;
pModMax = pModTrav;
}
pModTrav = pModTrav->pMod; // Next module.
}
if (pModMax != NULL) {
if (pModMax->oe.filetype == FT_ROMIMAGE) {
*dwResult = (DWORD) pModMax;
return MODULEPOINTER_DLL;
}
}
} else {
//
// We assume it's a process
//
if (pth->pOwnerProc->oe.filetype == FT_ROMIMAGE) {
*dwResult = (DWORD) (pth->pOwnerProc);
return MODULEPOINTER_PROC;
}
}
return (MODULEPOINTER_ERROR);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static TOCentry*
GetTocPointer(
PTHREAD pth,
unsigned int pc
)
{
TOCentry* tocptr = NULL;
DWORD dwModulePointer = (DWORD) NULL;
DWORD dwMPFlag = GetModulePointer(pth, pc, &dwModulePointer);
switch (dwMPFlag) {
case MODULEPOINTER_NK: {
// nk.exe: tocptr-> first entry in ROM
tocptr=(TOCentry *)(pTOC+1);
break;
}
case MODULEPOINTER_DLL: {
PMODULE pMod = (PMODULE) dwModulePointer;
tocptr = pMod->oe.tocptr;
break;
}
case MODULEPOINTER_PROC: {
PPROCESS pProc = (PPROCESS) dwModulePointer;
tocptr = pProc->oe.tocptr;
break;
}
default: {
// Error
tocptr = NULL;
}
}
return (tocptr);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
static HANDLE
GetModHandle(
PTHREAD pth,
unsigned int pc
)
{
HANDLE hModule;
DWORD dwModulePointer = (DWORD) NULL;
DWORD dwMPFlag = GetModulePointer(pth, pc, &dwModulePointer);
switch (dwMPFlag) {
case MODULEPOINTER_NK: {
// nk.exe is always the first process
hModule = (HANDLE) ProcArray[0].hProc;
break;
}
case MODULEPOINTER_DLL: {
// A DLL doesn't have a handle, so return the pointer.
hModule = (HANDLE) dwModulePointer;
break;
}
case MODULEPOINTER_PROC: {
hModule = (HANDLE) dwModulePointer;
break;
}
default: {
// Error
hModule = INVALID_HANDLE_VALUE;
}
}
return (hModule);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPCSTR
GetModName(
PTHREAD pth,
unsigned int pc
)
{
LPCSTR pszModName = NULL;
TOCentry* tocptr;
tocptr = GetTocPointer(pth, pc);
if (tocptr != NULL) {
pszModName = tocptr->lpszFileName;
}
return (pszModName);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Note: this was called GetSymbol but that didn't want to compile...
static LPBYTE
GetFuncSymbol(LPBYTE lpSym, DWORD dwSymNum)
{
while (dwSymNum > 0) {
while (*lpSym++);
dwSymNum--;
}
return lpSym;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPCSTR
GetFunctionName(
PTHREAD pth,
unsigned int pc
)
{
LPCSTR pszFunctionName = NULL;
TOCentry *tocptr; // table of contents entry pointer
PROFentry *profptr=NULL; // profile entry pointer
SYMentry *symptr; // profiler symbol entry pointer
unsigned int iMod; // module enty in TOC
unsigned int iSym; // symbol counter
if (!pTOC->ulProfileOffset) {
//
// No symbols available.
//
return (NULL);
}
if (pc & 0x80000000) {
//
// These addresses belong to NK.EXE.
//
if (pc >= 0xA0000000) {
//
// Hit a PSL exception address or perhaps a KDATA routine. No name.
//
return (NULL);
}
//
// Mask off the caching bit.
//
pc &= 0xdfffffff;
}
//
// Find the TOC entry if one exists. If not in ROM, then we can't get a name.
//
tocptr = GetTocPointer(pth, pc);
if (tocptr == NULL) {
return (NULL);
}
//
// Compute the module number
//
iMod= ((DWORD)tocptr - (DWORD)(pTOC+1)) / sizeof(TOCentry);
//
// make profptr point to entry for this module
//
profptr = (PROFentry *)pTOC->ulProfileOffset;
profptr += iMod;
//
// If there are any symbols in this module, scan for the function.
//
if (profptr->ulNumSym) {
unsigned int iClosestSym; // index of nearest symbol entry
SYMentry* pClosestSym; // ptr to nearest symbol entry
iSym = 0;
symptr=(SYMentry*)profptr->ulHitAddress;
iClosestSym = iSym;
pClosestSym = symptr;
//
// Scan the whole list of symbols, looking for the closest match.
//
while ((iSym < profptr->ulNumSym) && (pClosestSym->ulFuncAddress != pc)) {
// Keep track of the closest symbol found
if ((symptr->ulFuncAddress <= pc)
&& (symptr->ulFuncAddress > pClosestSym->ulFuncAddress)) {
iClosestSym = iSym;
pClosestSym = symptr;
}
iSym++;
symptr++;
}
pszFunctionName = (LPCSTR) GetFuncSymbol((LPBYTE) profptr->ulSymAddress, iClosestSym);
}
return (pszFunctionName);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
GetThreadName(
PTHREAD pth,
HANDLE* hModule,
WCHAR* szThreadFunctionName
)
{
DWORD dwProgramCounter = 0;
//
// Return a pointer to the thread's name if available.
//
if (pth != NULL) {
// The thread's program counter is saved off when it is created.
dwProgramCounter = pth->dwStartAddr;
if (hModule != NULL) {
*hModule = GetModHandle(pth, dwProgramCounter);
}
if (szThreadFunctionName != NULL) {
if (dwProgramCounter == (DWORD) CreateNewProc) {
//
// Creating a new process, so use the proc name instead of the func
//
LPSTR lpszTemp;
// First try to use the TOC to get the process name
if (pth->pOwnerProc
&& (pth->pOwnerProc->oe.filetype == FT_ROMIMAGE)
&& (pth->pOwnerProc->oe.tocptr)
&& (lpszTemp = pth->pOwnerProc->oe.tocptr->lpszFileName)) {
KAsciiToUnicode(szThreadFunctionName, lpszTemp, MAX_PATH);
} else if (!InSysCall()) {
// If we are not inside a KCall we can use the proc struct
LPWSTR lpszTempW;
if (pth->pOwnerProc
&& (lpszTempW = pth->pOwnerProc->lpszProcName)) {
DWORD dwLen = strlenW(lpszTempW) + 1;
memcpy(szThreadFunctionName, lpszTempW, dwLen * sizeof(WCHAR));
} else {
szThreadFunctionName[0] = 0;
}
} else {
// Otherwise we have no way to get the thread's name
szThreadFunctionName[0] = 0;
}
} else {
//
// Look up the function name
//
LPSTR lpszTemp = (LPSTR) GetFunctionName(pth, dwProgramCounter);
if (lpszTemp) {
KAsciiToUnicode(szThreadFunctionName, lpszTemp, MAX_PATH);
} else {
szThreadFunctionName[0] = 0;
}
}
}
} else {
if (hModule != NULL) {
*hModule = INVALID_HANDLE_VALUE;
}
if (szThreadFunctionName != NULL) {
szThreadFunctionName[0] = 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -