📄 xdbioctls.c
字号:
/*******************************************************************
fillbuffer
read the target trace buffer and store it in the application buffer
internal function
*********************************************************************/
static void fillbuffer(char* pCurrentTraceBuffer)
{
register int i = 0;
for (i=0;i<256;i++) {
*pCurrentTraceBuffer++ = (unsigned char)XSCBwrReadTraceByte();
}
}
/*******************************************************************
trace_add_current
*********************************************************************/
static void trace_add_current(BYTE * ptracebuffer)
{
//add Task info
*ptracebuffer++ = (BYTE)(CurrentTaskID >> 24);
*ptracebuffer++ = (BYTE)(CurrentTaskID >> 16);
*ptracebuffer++ = (BYTE)(CurrentTaskID >> 8);
*ptracebuffer++ = (BYTE)(CurrentTaskID >> 0);
XSCBwrSaveTrace(ptracebuffer);
}
/*****************************************************************
trace_admin_multi
Administration of the multiple trace buffers
two modes are supported: fill-once and wrap-around
fill-once means: if the application trace buffer is full
the target stops
wrap-around means: if the application trace buffer is full the
oldest entry in the application trace buffer
is overwritten with the current trace buffer.
/*****************************************************************/
static int trace_admin_multi(char** pbuffer)
{
if(CFGBlock.EndAddress == CFGBlock.StartAddress &&
CFGBlock.StartAddress == (int) CFGBlock.pTraceBuffer){//empty buffer
/*return address of the current trace buffer block */
*pbuffer =(char*) CFGBlock.StartAddress;
CFGBlock.EndAddress += XDBTRACEBUFFERBLOCKSIZE;
return FALSE; //not full
} else {
if(CFGBlock.EndAddress > CFGBlock.StartAddress){
//at least one block free for the current Trace block
if(CFGBlock.EndAddress + XDBTRACEBUFFERBLOCKSIZE ==
CFGBlock.StartAddress + CFGBlock.TraceBufferSize) {
*pbuffer =(char*) CFGBlock.EndAddress;
CFGBlock.EndAddress += XDBTRACEBUFFERBLOCKSIZE;
if(CFGBlock.TraceMode == FILL_ONCE){
return TRUE; // full after store this block
}else { //WRAP AROUND
return FALSE;
}
}else{
if(CFGBlock.EndAddress >=
CFGBlock.StartAddress + CFGBlock.TraceBufferSize)
{// WRAP AROUND occur
if(CFGBlock.TraceMode == FILL_ONCE){
return TRUE;/*buffer already full stop trace*/
}
*pbuffer =(char*) CFGBlock.StartAddress;
CFGBlock.StartAddress += XDBTRACEBUFFERBLOCKSIZE;
CFGBlock.EndAddress = CFGBlock.StartAddress;
return FALSE;
}else{
*pbuffer =(char*) CFGBlock.EndAddress;
CFGBlock.EndAddress += XDBTRACEBUFFERBLOCKSIZE;
}
}
}
else
{// has wrapped around // Startaddress == EndAddress
if(CFGBlock.EndAddress ==
(int) CFGBlock.pTraceBuffer + CFGBlock.TraceBufferSize)
{// WRAP AROUND occur
*pbuffer =(char*) CFGBlock.pTraceBuffer;
CFGBlock.StartAddress = (int)CFGBlock.pTraceBuffer+
XDBTRACEBUFFERBLOCKSIZE;
CFGBlock.EndAddress = CFGBlock.StartAddress;
if(CFGBlock.TraceMode == FILL_ONCE)
return TRUE; // full after store this block
}else
{
*pbuffer =(char*) CFGBlock.EndAddress;
CFGBlock.StartAddress += XDBTRACEBUFFERBLOCKSIZE;
CFGBlock.EndAddress = CFGBlock.StartAddress;
}
}
return FALSE;
}
}
/*-------------------------------------------------------------------------
* Function: IsUserModeCapture
*-------------------------------------------------------------------------
* Description: Determine if trace block contains user mode code
*-------------------------------------------------------------------------
* Return: BOOL (TRUE = buffer contains usermode code)
*-------------------------------------------------------------------------
*/
static BOOL IsUserModeCapture( BYTE* pTrcBuf )
{
register BYTE * p;
register DWORD Address;
for ( p = &pTrcBuf[256]; p > pTrcBuf; p-- ) {
switch(*p & 0xF0) {
case 0x90: // indirect branch
case 0xD0: // indirect branch with chkpt
p -= 4;
Address = (p[0] << 24) | ( p[1] << 16 ) | (p[2] << 8) | p[3];
if ( Address < 0x80000000) { // user mode ?
return TRUE;
}
break;
}
}
return FALSE;
}
/*-------------------------------------------------------------------------
* Function: XSCBwrHandleTraceBufferException
*-------------------------------------------------------------------------
* Description: Exception handler for the trace buffer full exception
*-------------------------------------------------------------------------
*/
void XSCBwrHandleTraceBufferException (void)
{
char* pBuffer;
static BYTE NewBuffer[XDBTRACEBUFFERBLOCKSIZE];
// temporary stoage for new buffer
//
XSCBwrSaveTrace(&NewBuffer[4]);
// check if usermode code is in this capture
//
if ( IsUserModeCapture(&NewBuffer[4]) ) {
trace_admin_multi(&pBuffer);
memcpy( pBuffer, NewBuffer, XDBTRACEBUFFERBLOCKSIZE);
}
}
/*-------------------------------------------------------------------------
* Function: XSCBwrExecutionTraceOn
*-------------------------------------------------------------------------
* Description: enable trace buffer recording
*-------------------------------------------------------------------------
*/
void XSCBwrExecutionTraceOn(DWORD TID)
{
if (CFGBlock.TraceMode==TRACE_OFF)
return;
CurrentTaskID = TID;
XSCBwrEnableTrace();
}
/*-------------------------------------------------------------------------
* Function: XSCBwrExecutionTraceOff
*-------------------------------------------------------------------------
* Description: disable trace buffer recording
*-------------------------------------------------------------------------
*/
void XSCBwrExecutionTraceOff(DWORD ID)
{
XSCBwrDisableTrace();
}
static BOOL GetTraceConfigIoctl(DWORD dwIoControlCode,
LPVOID lpInBuf, DWORD nInBufSize,
LPVOID lpOutBuf, DWORD nOutBufSize,
LPDWORD lpBytesReturned)
{
BOOL retval = FALSE;
// check output buffer
//
if ( (lpOutBuf == NULL) || (nOutBufSize < sizeof(DWORD) ) ) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return (retval);
}
*(DWORD *)lpOutBuf = (DWORD)&CFGBlock;
// Set the return value
retval = TRUE;
*lpBytesReturned = 4;
return (retval);
}
/*-------------------------------------------------------------------------
* Function: TraceControlIoctl
*-------------------------------------------------------------------------
* Description: Process trace commands from the XDB Browser
*-------------------------------------------------------------------------
* Pre/Side/Post: prototype matches OEMIoControl
*-------------------------------------------------------------------------
*/
static BOOL TraceControlIoctl(DWORD dwIoControlCode,
LPVOID lpInBuf, DWORD nInBufSize,
LPVOID lpOutBuf, DWORD nOutBufSize,
LPDWORD lpBytesReturned)
{
// Set the default return value
BOOL retval = FALSE;
if ( (lpInBuf == NULL) || (nInBufSize < 9) || (lpBytesReturned == NULL) )
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return (retval);
}
switch( ((char *)lpInBuf)[8] ) {
case 0: // diable trace
CFGBlock.TraceMode = TRACE_OFF;
NKSetDataAbortHandler( pfOSDataAbortHandler );
// Need to flush caches to have handler written to exception area
OEMCacheRangeFlush(0, 0, CACHE_SYNC_ALL);
break;
case 1: // enable trace
NKSetDataAbortHandler( XSCBwrTraceDataAbortHandler );
// Need to flush caches to have handler written to exception area
OEMCacheRangeFlush(0, 0, CACHE_SYNC_ALL);
CFGBlock.TraceMode = WRAP_AROUND;
break;
case 2: // clear trace;
memset( (LPVOID)CFGBlock.pTraceBuffer, 0, CFGBlock.TraceBufferSize);
CFGBlock.StartAddress = CFGBlock.pTraceBuffer;
CFGBlock.EndAddress = CFGBlock.pTraceBuffer;
break;
}
retval = TRUE;
*lpBytesReturned = 0;
return retval;
}
/*-------------------------------------------------------------------------
* Function: ReadTraceIoctl
*-------------------------------------------------------------------------
* Description: Process trace read command from the XDB Browser
*-------------------------------------------------------------------------
* Pre/Side/Post: prototype matches OEMIoControl
*-------------------------------------------------------------------------
*/
static BOOL ReadTraceIoctl(DWORD dwIoControlCode,
LPVOID lpInBuf, DWORD nInBufSize,
LPVOID lpOutBuf, DWORD nOutBufSize,
LPDWORD lpBytesReturned)
{
// Set the default return value
BOOL retval = FALSE;
if ( (lpBytesReturned == NULL) )
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return (retval);
}
// check output buffer
//
if ( (lpOutBuf == NULL) || (nOutBufSize < 264 ) )
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return (retval);
}
// copy trace buffer into user buffer
//
XSCBwrSaveTrace(lpOutBuf);
*lpBytesReturned = 264;
retval = TRUE;
return (retval);
}
/*-------------------------------------------------------------------------
* Function: XSCBwrIoControl
*-------------------------------------------------------------------------
* Description: Entry point for all debug extension IOCTLS
* This function is called from OEMIoControl on every
* browser IOCTL
*-------------------------------------------------------------------------
* Pre/Side/Post: prototype matches OEMIoControl
*-------------------------------------------------------------------------
*/
BOOL XSCBwrIoControl(
UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize)
{
BOOL retval = FALSE;
switch( code ) {
case IOCTL_XSDBG_READCOPROCESSOR:
retval = ReadCoProcessorIoctl( code, pInpBuffer, inpSize,
pOutBuffer, outSize, pOutSize);
break;
case IOCTL_XSDBG_WRITECOPROCESSOR:
retval = WriteCoProcessorIoctl( code, pInpBuffer, inpSize,
pOutBuffer, outSize, pOutSize);
break;
case IOCTL_XSDBG_SETTASK:
retval = SetTaskIoctl( code, pInpBuffer, inpSize,
pOutBuffer, outSize, pOutSize);
break;
/* These tree IOCTLs are implemented by the BSP
case IOCTL_XSDBG_QUERYCTXREGS:
retval = QueryContextRegistersIoctl(code, pInpBuffer, inpSize,
pOutBuffer, outSize, pOutSize);
break;
case IOCTL_XSDBG_READCTXREGS:
retval = ReadContextRegisterIoctl( code, pInpBuffer, inpSize,
pOutBuffer, outSize, pOutSize);
break;
case IOCTL_XSDBG_WRITECTXREGS:
retval = WriteContextRegisterIoctl( code, pInpBuffer, inpSize,
pOutBuffer, outSize, pOutSize);
break;
*/
case IOCTL_XSDBG_TRACECONTROL:
retval = TraceControlIoctl(code, pInpBuffer, inpSize,
pOutBuffer, outSize, pOutSize);
break;
case IOCTL_XSDBG_READTRACE:
retval = ReadTraceIoctl( code, pInpBuffer, inpSize,
pOutBuffer, outSize, pOutSize);
break;
case IOCTL_XSDBG_READKMEM:
retval = ReadKMemIoctl( code, pInpBuffer, inpSize,
pOutBuffer, outSize, pOutSize);
break;
case IOCTL_XSDBG_GETTRACECONFIG:
retval = GetTraceConfigIoctl( code, pInpBuffer, inpSize,
pOutBuffer, outSize, pOutSize);
break;
case IOCTL_XSDBG_GETVERSION:
retval = GetVersionIoctl( code, pInpBuffer, inpSize,
pOutBuffer, outSize, pOutSize);
break;
default:
SetLastError(ERROR_NOT_SUPPORTED);
break;
}
return retval;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -