windows-nt/Source/XPSP1/NT/base/busdrv/acpi/tools/kdext/context.c

1033 lines
22 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
context.c
Abstract:
Dumps the AML Context Structure in Human-Readable-Form (HRF)
Author:
Stephane Plante (splante) 21-Mar-1997
Environment:
User Mode.
Revision History:
--*/
#include "pch.h"
VOID
dumpAccessFieldObject(
IN ULONG_PTR AccessFieldAddress,
IN ULONG Verbose,
IN ULONG IndentLevel
)
{
ACCFIELDOBJ fieldObj;
BOOL result;
UCHAR buffer[80];
ULONG returnLength;
//
// Initialize the indent buffer
//
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
memset( buffer, ' ', IndentLevel );
buffer[IndentLevel] = '\0';
result = ReadMemory(
AccessFieldAddress,
&fieldObj,
sizeof(ACCFIELDOBJ),
&returnLength
);
if (result != TRUE ||
returnLength != sizeof(ACCFIELDOBJ) ||
fieldObj.FrameHdr.dwSig != SIG_ACCFIELDOBJ) {
dprintf(
"%sdumpAccessFieldUnit: Coult not read ACCFIELDOBJ %08lx\n",
buffer,
AccessFieldAddress
);
return;
}
dprintf(
"%sAccess Field Object - %08lx\n"
"%s Field Data Object: %08lx\n",
buffer, AccessFieldAddress,
buffer, fieldObj.pdataObj
);
if (fieldObj.pdataObj != NULL && (Verbose & VERBOSE_CONTEXT)) {
dumpPObject(
(ULONG_PTR) fieldObj.pdataObj,
Verbose,
IndentLevel + 4
);
}
dprintf(
"%s Target Buffer: %08lx - %08lx\n"
"%s Access Size: %08lx\n"
"%s # of Accesses: %08lx\n"
"%s Data Mask: %08lx\n"
"%s # of Left Bits: %08lx\n"
"%s # of Right Bits: %08lx\n"
"%s Index to #/Accesses: %08lx\n"
"%s Temp Data: %08lx\n",
buffer, fieldObj.pbBuff, fieldObj.pbBuffEnd,
buffer, fieldObj.dwAccSize,
buffer, fieldObj.dwcAccesses,
buffer, fieldObj.dwDataMask,
buffer, fieldObj.iLBits,
buffer, fieldObj.iRBits,
buffer, fieldObj.iAccess,
buffer, fieldObj.dwData
);
dprintf(
"%s Field Descriptor: %p\n",
buffer,
( (ULONG_PTR) &(fieldObj.fd) - (ULONG_PTR) &fieldObj + AccessFieldAddress )
);
dumpFieldAddress(
( (ULONG_PTR) &(fieldObj.fd) - (ULONG_PTR) &fieldObj + AccessFieldAddress ),
Verbose,
IndentLevel + 4
);
}
VOID
dumpAccessFieldUnit(
IN ULONG_PTR AccessFieldAddress,
IN ULONG Verbose,
IN ULONG IndentLevel
)
{
ACCFIELDUNIT fieldUnit;
BOOL result;
UCHAR buffer[80];
ULONG returnLength;
//
// Initialize the indent buffer
//
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
memset( buffer, ' ', IndentLevel );
buffer[IndentLevel] = '\0';
result = ReadMemory(
AccessFieldAddress,
&fieldUnit,
sizeof(ACCFIELDUNIT),
&returnLength
);
if (result != TRUE ||
returnLength != sizeof(ACCFIELDUNIT) ||
fieldUnit.FrameHdr.dwSig != SIG_ACCFIELDUNIT) {
dprintf(
"%sdumpAccessFieldUnit: Coult not read ACCFIELDUNIT %08lx\n",
buffer,
AccessFieldAddress
);
return;
}
dprintf(
"%sAccess Field Unit - %08lx\n"
"%s Field Data Object: %08lx\n",
buffer, AccessFieldAddress,
buffer, fieldUnit.pdataObj
);
if (fieldUnit.pdataObj != NULL && (Verbose & VERBOSE_CONTEXT)) {
dumpPObject(
(ULONG_PTR) fieldUnit.pdataObj,
Verbose,
IndentLevel + 4
);
}
dprintf(
"%s Source/Result Object: %08lx\n",
buffer,
fieldUnit.pdata
);
if (fieldUnit.pdata != NULL && (Verbose & VERBOSE_CONTEXT)) {
dumpPObject(
(ULONG_PTR) fieldUnit.pdata,
Verbose,
IndentLevel + 4
);
}
}
VOID
dumpAmlTerm(
IN ULONG_PTR AmlTermAddress,
IN ULONG Verbose,
IN ULONG IndentLevel
)
{
AMLTERM amlTerm;
BOOL result;
INT i;
UCHAR buffer[80];
ULONG returnLength;
//
// Initialize the indent buffer
//
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
memset( buffer, ' ', IndentLevel );
buffer[IndentLevel] = '\0';
result = ReadMemory(
AmlTermAddress,
&amlTerm,
sizeof(AMLTERM),
&returnLength
);
if (result != TRUE || returnLength != sizeof(AMLTERM)) {
dprintf(
"\n%sdumpAmlTerm: Could not read AMLTERM 0x%08lx\n",
buffer,
AmlTermAddress
);
return;
}
if (amlTerm.pszTermName != NULL) {
result = ReadMemory(
(ULONG_PTR) amlTerm.pszTermName,
Buffer,
32,
&returnLength
);
if (result && returnLength <= 32) {
Buffer[returnLength] = '\0';
dprintf(" - %s\n", Buffer );
}
}
}
VOID
dumpCall(
IN ULONG_PTR CallAddress,
IN ULONG Verbose,
IN ULONG IndentLevel
)
{
BOOL result;
CALL call;
INT i;
UCHAR buffer[80];
ULONG returnLength;
//
// Initialize the indent buffer
//
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
memset( buffer, ' ', IndentLevel );
buffer[IndentLevel] = '\0';
result = ReadMemory(
CallAddress,
&call,
sizeof(CALL),
&returnLength
);
if (result != TRUE ||
returnLength != sizeof(CALL) ||
call.FrameHdr.dwSig != SIG_CALL) {
dprintf(
"%sdumpCall: Coult not read CALL %08lx\n",
buffer,
CallAddress
);
return;
}
dprintf(
"%sCall - %08lx\n", buffer, CallAddress
);
//
// Method
//
dprintf(
"%s Method: %08lx\n",
buffer,
call.pnsMethod
);
if (call.pnsMethod != NULL && (Verbose & VERBOSE_CONTEXT)) {
dumpNSObject( (ULONG_PTR) call.pnsMethod, Verbose, IndentLevel + 4);
}
//
// Previous Call Frame
//
if (Verbose & VERBOSE_CALL) {
dprintf(
"%s Previous Call Frame: %08lx\n"
"%s Previous Owner: %08lx\n",
buffer,
call.pcallPrev,
buffer,
call.pownerPrev
);
if (call.pownerPrev != NULL && (Verbose & VERBOSE_CONTEXT)) {
dumpObjectOwner(
(ULONG_PTR) call.pownerPrev,
IndentLevel + 2
);
}
}
if (Verbose & VERBOSE_CONTEXT) {
//
// Dump arguments
//
dprintf(
"%s Arguments (Current): %1d (%1d)\n",
buffer,
call.icArgs,
call.iArg
);
for (i = 0; i < call.icArgs; i++) {
dprintf(
"%s Argument(%d): %p\n",
buffer,
i,
(ULONG_PTR) (call.pdataArgs + i)
);
dumpPObject(
(ULONG_PTR) (call.pdataArgs + i),
Verbose,
IndentLevel + 4
);
}
dprintf(
"%s Result: %08lx\n",
buffer,
call.pdataResult
);
if (call.pdataResult != NULL) {
dumpPObject(
(ULONG_PTR) call.pdataResult,
Verbose,
IndentLevel + 4
);
}
if (Verbose & VERBOSE_CALL) {
dprintf(
"%s Locals:\n",
buffer
);
for (i = 0; i < MAX_NUM_LOCALS; i++) {
dumpObject(
(ULONG) ( (PUCHAR) &(call.Locals[i]) - (PUCHAR) &call) +
CallAddress,
&(call.Locals[i]),
Verbose,
IndentLevel + 4
);
}
}
}
}
VOID
dumpContext(
IN ULONG_PTR ContextAddress,
IN ULONG Verbose
)
/*++
Routine Description:
This routine dumps a context structure in HRF
Arguments:
ContextAddress - Where on the target machine the context is located
Verbose - How verbose we should be
Return Value:
None
--*/
{
ULONG_PTR displacement;
BOOL result;
CTXT context;
ULONG returnLength;
//
// Read the context from the target
//
result = ReadMemory(
ContextAddress,
&context,
sizeof(CTXT),
&returnLength
);
if (result != TRUE || returnLength != sizeof(CTXT) ) {
dprintf(
"dumpContext: could not read CTXT %08lx\n",
ContextAddress
);
return;
}
//
// Is it a context?
//
if (context.dwSig != SIG_CTXT) {
dprintf(
"dumpContext: Signature (%08lx) != SIG_CTXT (%08lx)\n",
context.dwSig,
SIG_CTXT
);
return;
}
dprintf("Context - %08lx-%08lx\n",ContextAddress, context.pbCtxtEnd );
if (Verbose & VERBOSE_CONTEXT) {
dprintf(
" AllocatedContextList: F:%08lx B:%08lx\n"
" QueingContextList: F:%08lx B:%08lx\n"
" ContextListHead: %08lx\n"
" SynchronizeLevel: %08lx\n"
" CurrentOpByte: %08lx\n"
" AsyncCallBack: %08lx",
context.listCtxt.plistNext, context.listCtxt.plistPrev,
context.listQueue.plistNext, context.listQueue.plistPrev,
context.pplistCtxtQueue,
context.dwSyncLevel,
context.pbOp,
context.pfnAsyncCallBack
);
if (context.pfnAsyncCallBack != NULL) {
GetSymbol(
context.pfnAsyncCallBack,
Buffer,
&displacement
);
dprintf(" %s",
Buffer
);
}
dprintf(
"\n"
" AsyncCallBackContext: %08lx\n"
" AsyncDataCallBack: %08lx\n",
context.pvContext,
context.pdataCallBack
);
}
dprintf(
" Flags: %08lx",
context.dwfCtxt
);
if (context.dwfCtxt & CTXTF_TIMER_PENDING) {
dprintf(" Timer");
}
if (context.dwfCtxt & CTXTF_TIMEOUT) {
dprintf(" Timeout");
}
if (context.dwfCtxt & CTXTF_READY) {
dprintf(" Ready");
}
if (context.dwfCtxt & CTXTF_NEED_CALLBACK) {
dprintf(" CallBack");
}
dprintf("\n");
dprintf(
" NameSpace Object: %08lx\n",
context.pnsObj
);
if (Verbose & VERBOSE_CONTEXT) {
dprintf(
" NameSpace Scope: %08lx\n"
" NameSpace Owner: %08lx\n",
context.pnsScope,
context.powner
);
if (context.powner != NULL) {
dumpObjectOwner(
(ULONG_PTR) context.powner,
2
);
}
}
dprintf(
" Current Call Frame: %08lx\n",
context.pcall
);
if (context.pcall != NULL) {
dumpCall(
(ULONG_PTR) context.pcall,
(Verbose & ~VERBOSE_CONTEXT),
4
);
}
dumpStack(
ContextAddress,
&context,
Verbose,
2
);
}
VOID
dumpFieldAddress(
IN ULONG_PTR FieldAddress,
IN ULONG Verbose,
IN ULONG IndentLevel
)
{
FIELDDESC fd;
BOOL result;
UCHAR buffer[80];
ULONG returnLength;
//
// Initialize the indent buffer
//
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
memset( buffer, ' ', IndentLevel );
buffer[IndentLevel] = '\0';
result = ReadMemory(
FieldAddress,
&fd,
sizeof(FIELDDESC),
&returnLength
);
if (result != TRUE ||
returnLength != sizeof(FIELDDESC) ) {
dprintf(
"%sdumpFieldAddress: Coult not read FIELDDESC %08lx\n",
buffer,
FieldAddress
);
return;
}
dprintf(
"%sField Descriptor - %08lx\n"
"%s ByteOffset: %08lx\n"
"%s Start Bit Position: %08lx\n"
"%s Number of Bits: %08lx\n"
"%s Flags: %08lx\n",
buffer, FieldAddress,
buffer, fd.dwByteOffset,
buffer, fd.dwStartBitPos,
buffer, fd.dwNumBits,
buffer, fd.dwFieldFlags
);
}
VOID
dumpListContexts(
IN VOID
)
/*++
--*/
{
PLIST pList;
PLIST pListNext;
}
VOID
dumpObjectOwner(
IN ULONG_PTR ObjOwnerAddress,
IN ULONG IndentLevel
)
{
BOOL result;
OBJOWNER objowner;
UCHAR buffer[80];
ULONG returnLength;
//
// Initialize the indent buffer
//
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
memset( buffer, ' ', IndentLevel );
buffer[IndentLevel] = '\0';
result = ReadMemory(
ObjOwnerAddress,
&objowner,
sizeof(OBJOWNER),
&returnLength
);
if (result == TRUE &&
returnLength == sizeof(OBJOWNER) &&
objowner.dwSig == SIG_OBJOWNER) {
dprintf(
"%sObjectOwner - %08lx\n"
"%s NameSpaceObject: %08lx\n"
"%s List: F:%08lx B:%08lx\n",
buffer,
ObjOwnerAddress,
buffer,
objowner.pnsObjList,
buffer,
objowner.list.plistNext,
objowner.list.plistPrev
);
} else {
dprintf(
"%sdumpObjectOwner: Could not read OBJOWNER %08lx\n",
buffer,ObjOwnerAddress
);
}
}
VOID
dumpScope(
IN ULONG_PTR ScopeAddress,
IN ULONG Verbose,
IN ULONG IndentLevel
)
{
BOOL result;
SCOPE scope;
UCHAR indent[80];
ULONG returnLength;
//
// Initialize the indent buffer
//
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
memset( indent, ' ', IndentLevel );
indent[IndentLevel] = '\0';
result = ReadMemory(
ScopeAddress,
&scope,
sizeof(SCOPE),
&returnLength
);
if (result != TRUE ||
returnLength != sizeof(SCOPE) ||
scope.FrameHdr.dwSig != SIG_SCOPE) {
dprintf(
"%sdumpScope: Coult not read SCOPE %08lx\n",
indent,
ScopeAddress
);
return;
}
dprintf(
"%sScope - %08lx\n",
indent,
ScopeAddress
);
dprintf(
"%s ScopeEnd: %08lx\n"
"%s ReturnAddress: %08lx\n"
"%s Previous Scope: %08lx\n",
indent,
scope.pbOpEnd,
indent,
scope.pbOpRet,
indent,
scope.pnsPrevScope
);
if (Verbose & VERBOSE_CALL) {
dumpNSObject( (ULONG_PTR) scope.pnsPrevScope, Verbose, IndentLevel + 4);
}
dprintf(
"%s Previous Owner: %08lx\n",
indent,
scope.pownerPrev
);
if (Verbose & VERBOSE_CALL) {
dumpObjectOwner(
(ULONG_PTR) scope.pownerPrev,
IndentLevel + 4
);
}
dprintf(
"%s Result Object: %08lx\n",
indent,
scope.pdataResult
);
if (scope.pdataResult != NULL && (Verbose & VERBOSE_CALL) ) {
dumpPObject(
(ULONG_PTR) scope.pdataResult,
Verbose,
IndentLevel + 4
);
}
}
VOID
dumpStack(
IN ULONG_PTR ContextAddress,
IN PCTXT Context,
IN ULONG Verbose,
IN ULONG IndentLevel
)
{
ULONG_PTR displacement;
BOOL result;
FRAMEHDR frame;
PUCHAR frameAddress;
UCHAR indent[80];
UCHAR buffer[5];
ULONG returnLength;
//
// Initialize the indent buffer
//
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
memset( indent, ' ', IndentLevel );
indent[IndentLevel] = '\0';
buffer[4] = '\0';
dprintf(
"%sStack - %p-%08lx (%08lx)\n",
indent,
ContextAddress,
Context->LocalHeap.pbHeapEnd,
Context->pbCtxtEnd
);
//
// Calculate where the first frame lies
//
frameAddress = Context->LocalHeap.pbHeapEnd;
while (frameAddress < Context->pbCtxtEnd) {
result = ReadMemory(
(ULONG_PTR) frameAddress,
&frame,
sizeof(FRAMEHDR),
&returnLength
);
if (result != TRUE ||
returnLength != sizeof(FRAMEHDR)) {
dprintf(
"%sdumpStack: could not read FRAMEHDR %08lx\n",
indent,
(ULONG_PTR) frameAddress
);
return;
}
memcpy( buffer, (PUCHAR) &(frame.dwSig), 4 );
dprintf(
"%s %p: %s - (Length %08lx) (Flags %08lx)\n"
"%s ParseFunction %08lx",
indent,
(ULONG_PTR) frameAddress,
buffer,
frame.dwLen,
frame.dwfFrame,
indent,
frame.pfnParse
);
if (frame.pfnParse != NULL) {
GetSymbol(
frame.pfnParse,
Buffer,
&displacement
);
dprintf(" %s",
Buffer
);
}
dprintf("\n");
//
// Do we know how to crack the frame?
//
switch(frame.dwSig) {
case SIG_CALL:
dumpCall(
(ULONG_PTR) frameAddress,
Verbose,
IndentLevel + 4
);
break;
case SIG_SCOPE:
dumpScope(
(ULONG_PTR) frameAddress,
Verbose,
IndentLevel + 4
);
break;
case SIG_TERM:
dumpTerm(
(ULONG_PTR) frameAddress,
Verbose,
IndentLevel + 4
);
break;
case SIG_ACCFIELDUNIT:
dumpAccessFieldUnit(
(ULONG_PTR) frameAddress,
Verbose,
IndentLevel + 4
);
break;
case SIG_ACCFIELDOBJ:
dumpAccessFieldObject(
(ULONG_PTR) frameAddress,
Verbose,
IndentLevel + 4
);
break;
}
//
// Make sure that there is some white space present
//
dprintf("\n\n");
//
// Next11
//
frameAddress += frame.dwLen;
}
}
VOID
dumpTerm(
IN ULONG_PTR TermAddress,
IN ULONG Verbose,
IN ULONG IndentLevel
)
{
BOOL result;
INT i;
TERM term;
UCHAR indent[80];
ULONG returnLength;
//
// Initialize the indent buffer
//
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
memset( indent, ' ', IndentLevel );
indent[IndentLevel] = '\0';
result = ReadMemory(
TermAddress,
&term,
sizeof(TERM),
&returnLength
);
if (result != TRUE ||
returnLength != sizeof(TERM) ||
term.FrameHdr.dwSig != SIG_TERM) {
dprintf(
"%sdumpTerm: Coult not read TERM %08lx\n",
indent,
TermAddress
);
return;
}
dprintf(
"%sTerm - %08lx\n",
indent,
TermAddress
);
dprintf(
"%s OpCodeStart: %08lx\n"
"%s OpCodeEnd: %08lx\n"
"%s ScopeEnd: %08lx\n"
"%s NameSpaceObject: %08lx\n",
indent,
term.pbOpTerm,
indent,
term.pbOpEnd,
indent,
term.pbScopeEnd,
indent,
term.pnsObj
);
if ( term.pnsObj != NULL && (Verbose & VERBOSE_CALL)) {
dumpNSObject( (ULONG_PTR) term.pnsObj, Verbose, IndentLevel + 4);
}
dprintf(
"%s Aml Term: %08lx",
indent,
term.pamlterm
);
if (term.pamlterm != NULL) {
dumpAmlTerm( (ULONG_PTR) term.pamlterm, Verbose, IndentLevel + 4);
} else {
dprintf("\n");
}
//
// Dump arguments
//
dprintf(
"%s Arguments (Current): %1d (%1d)\n",
indent,
term.icArgs,
term.iArg
);
for (i = 0; i < term.icArgs; i++) {
dprintf(
"%s Argument(%d): %p\n",
indent,
i,
(ULONG_PTR) (term.pdataArgs + i)
);
if (Verbose & VERBOSE_CALL) {
dumpPObject(
(ULONG_PTR) (term.pdataArgs + i),
Verbose,
IndentLevel + 4
);
}
}
dprintf(
"%s Result: %08lx\n",
indent,
term.pdataResult
);
if (term.pdataResult != NULL && (Verbose & VERBOSE_CALL) ) {
dumpPObject(
(ULONG_PTR) term.pdataResult,
Verbose,
IndentLevel + 4
);
}
}