windows-nt/Source/XPSP1/NT/base/busdrv/acpi/tools/kdext/stack.c
2020-09-26 16:20:57 +08:00

573 lines
10 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
stack.c
Abstract:
Dumps the AML Context Structure in Human-Readable-Form (HRF)
Author:
Stephane Plante (splante) 26-Oct-1997
Environment:
User Mode.
Revision History:
--*/
#include "pch.h"
VOID
stackArgument(
IN ULONG_PTR ObjectAddress
)
{
BOOL result;
OBJDATA object;
PUCHAR buffer = NULL;
ULONG returnLength;
//
// Read the object
//
result = ReadMemory(
ObjectAddress,
&object,
sizeof(OBJDATA),
&returnLength
);
if (!result || returnLength != sizeof(OBJDATA)) {
dprintf("_BAD_");
return;
}
if (object.pbDataBuff != 0) {
buffer = LocalAlloc( LPTR, object.dwDataLen+1 );
if (buffer == NULL) {
dprintf("_MEM_");
return;
}
result = ReadMemory(
(ULONG_PTR) object.pbDataBuff,
buffer,
object.dwDataLen,
&returnLength
);
if (!result || returnLength != object.dwDataLen) {
dprintf("_BUF_");
return;
}
}
switch (object.dwDataType) {
case OBJTYPE_INTDATA:
dprintf("0x%x", object.uipDataValue);
break;
case OBJTYPE_STRDATA:
buffer[object.dwDataLen] = '\0';
dprintf("%s",buffer);
break;
case OBJTYPE_BUFFDATA:
dprintf(
"<buffer> %08lx-%08lx",
object.pbDataBuff,
object.pbDataBuff+object.dwDataLen
);
break;
case OBJTYPE_PKGDATA:
dprintf("<package> %08lx", ObjectAddress );
break;
case OBJTYPE_FIELDUNIT:
dprintf("<fieldunit> %08lx", ObjectAddress );
break;
case OBJTYPE_DEVICE:
dprintf("<device> %08lx", ObjectAddress );
break;
case OBJTYPE_EVENT:
dprintf("<event> %08lx", ObjectAddress );
break;
case OBJTYPE_METHOD:
dprintf("<method> %08lx", ObjectAddress );
break;
case OBJTYPE_MUTEX:
dprintf("<mutex> %08lx", ObjectAddress );
break;
case OBJTYPE_OPREGION:
dprintf("<opregion> %08lx", ObjectAddress );
break;
case OBJTYPE_POWERRES:
dprintf("<powerres> %08lx", ObjectAddress );
break;
case OBJTYPE_PROCESSOR:
dprintf("<processor> %08lx", ObjectAddress );
break;
case OBJTYPE_THERMALZONE:
dprintf("<thermalzone> %08lx", ObjectAddress );
break;
case OBJTYPE_BUFFFIELD:
dprintf("<bufffield> %08lx", ObjectAddress );
break;
case OBJTYPE_DDBHANDLE:
dprintf("<ddbhandle> %08lx", ObjectAddress );
break;
case OBJTYPE_DEBUG:
dprintf("<debug> %08lx", ObjectAddress );
break;
case OBJTYPE_DATAALIAS:
dprintf("<dataalias> %08lx", ObjectAddress );
break;
case OBJTYPE_BANKFIELD:
dprintf("<bankfield> %08lx", ObjectAddress );
break;
case OBJTYPE_FIELD:
dprintf("<field> %08lx", ObjectAddress );
break;
case OBJTYPE_INDEXFIELD:
dprintf("<indexfield> %08lx", ObjectAddress );
break;
default:
dprintf("<unknown> %08lx", ObjectAddress );
break;
}
}
VOID
stackCall(
IN ULONG_PTR CallAddress
)
/*++
Format Displayed:
ResultAddress MethodName( Arg0, ..., ArgN )
--*/
{
ULONG_PTR address;
BOOL result;
CALL call;
INT i;
NSOBJ object;
PUCHAR objectPath;
ULONG returnLength;
result = ReadMemory(
CallAddress,
&call,
sizeof(CALL),
&returnLength
);
if (result != TRUE ||
returnLength != sizeof(CALL) ||
call.FrameHdr.dwSig != SIG_CALL) {
dprintf(
"stackCall: --- Coult not read call frame %08lx\n",
CallAddress
);
return;
}
if (call.pnsMethod == NULL) {
dprintf( "%08lx --- No method\n", CallAddress );
return;
}
//
// Display result address
//
dprintf("CALL %08lx ", CallAddress );
//
// Display the function name
//
objectPath = stackGetObjectPath( (ULONG_PTR) call.pnsMethod );
dprintf("%s(", objectPath);
//
// Display all parsed arguments;
//
for (i = 0; i < call.iArg; i++) {
//
// What is the address of the argument
//
address = (ULONG_PTR) &call.pdataArgs[i];
//
// Display that argument
//
stackArgument(
address
);
if (i < (call.icArgs - 1)) {
dprintf(",");
}
}
//
// Let the user know how many unprocessed arguments there are
//
for (; i < call.icArgs; i++) {
dprintf("_???_");
if (i < (call.icArgs-1)) {
dprintf(",");
}
}
dprintf(")\n");
}
PUCHAR
stackGetAmlTermPath(
IN ULONG_PTR AmlTermAddress
)
{
AMLTERM amlTerm;
BOOL result;
static UCHAR termPath[2049];
ULONG i;
ULONG resultLength;
result = ReadMemory(
AmlTermAddress,
&amlTerm,
sizeof(AMLTERM),
&resultLength
);
if (!result || resultLength != sizeof(AMLTERM)) {
return NULL;
}
if (amlTerm.pszTermName == NULL) {
return NULL;
}
result = ReadMemory(
(ULONG_PTR) amlTerm.pszTermName,
&termPath,
2048,
&resultLength
);
if (!result || resultLength == 0) {
return NULL;
}
termPath[resultLength] = '\0';
return termPath;
}
PUCHAR
stackGetObjectPath(
IN ULONG_PTR ObjectAddress
)
{
BOOL result;
NSOBJ object;
static UCHAR namePath[2049];
ULONG i;
ULONG resultLength;
//
// Read the object
//
result = ReadMemory(
ObjectAddress,
&object,
sizeof(NSOBJ),
&resultLength
);
if (!result || resultLength != sizeof(NSOBJ)) {
return NULL;
}
if (object.pnsParent == NULL) {
strcpy( namePath, "\\");
} else {
NSOBJ parent;
stackGetObjectPath( (ULONG_PTR) object.pnsParent );
result = ReadMemory(
(ULONG_PTR) object.pnsParent,
&parent,
sizeof(NSOBJ),
&resultLength
);
if (!result || resultLength != sizeof(NSOBJ)) {
return NULL;
}
if (parent.pnsParent != NULL) {
strcat(namePath, ".");
}
strncat( namePath, (PUCHAR) &(object.dwNameSeg), sizeof(NAMESEG) );
for (i = strlen(namePath); i > 0; --i) {
if (namePath[i-1] == '_') {
namePath[i-1] = '\0';
} else {
break;
}
}
}
return namePath;
}
VOID
stackTerm(
IN ULONG_PTR TermAddress
)
/*++
Format Displayed:
term TermAddress TermName( Arg0, ..., ArgN )
--*/
{
ULONG_PTR address;
BOOL result;
INT i;
NSOBJ object;
PUCHAR objectPath;
TERM term;
ULONG returnLength;
result = ReadMemory(
TermAddress,
&term,
sizeof(TERM),
&returnLength
);
if (result != TRUE ||
returnLength != sizeof(TERM) ||
term.FrameHdr.dwSig != SIG_TERM) {
dprintf(
"stackTerm: --- Coult not read call frame %08lx\n",
TermAddress
);
return;
}
if (term.pamlterm == NULL) {
dprintf( "%08lx --- No term\n", TermAddress );
return;
}
//
// Display result address
//
dprintf("TERM %08lx ", TermAddress );
//
// Display the function name
//
objectPath = stackGetAmlTermPath( (ULONG_PTR) term.pamlterm );
dprintf("%s(", objectPath);
//
// Display all parsed arguments;
//
for (i = 0; i < term.iArg; i++) {
//
// What is the address of the argument
//
address = (ULONG_PTR) &term.pdataArgs[i];
//
// Display that argument
//
stackArgument(
address
);
if (i < (term.icArgs - 1)) {
dprintf(",");
}
}
//
// Let the user know how many unprocessed arguments there are
//
for (; i < term.icArgs; i++) {
dprintf("_???_");
if (i < (term.icArgs-1)) {
dprintf(",");
}
}
dprintf(")\n");
}
VOID
stackTrace(
IN ULONG_PTR ContextAddress,
IN ULONG Verbose
)
/*++
Routine Description:
This routine dumps a context as a stack
Arguments:
ContextAddress - Where the stack is located
Verbose - How much information to display
Return Value:
None
--*/
{
BOOL callSeen = FALSE;
BOOL result;
CTXT context;
FRAMEHDR frame;
PUCHAR frameAddress;
ULONG returnLength;
//
// Read the context from the target
//
result = ReadMemory(
ContextAddress,
&context,
sizeof(CTXT),
&returnLength
);
if (result != TRUE || returnLength != sizeof(CTXT)) {
dprintf(
"stackTrace: --- Could not read Context %08lx\n",
ContextAddress
);
return;
}
if (context.dwSig != SIG_CTXT) {
dprintf(
"stackTrace: --- Not a Context (%08lx)\n",
context.dwSig
);
return;
}
//
// Begin to walk the frames
//
frameAddress = context.LocalHeap.pbHeapEnd;
while (frameAddress < context.pbCtxtEnd) {
result = ReadMemory(
(ULONG_PTR) frameAddress,
&frame,
sizeof(FRAMEHDR),
&returnLength
);
if (result != TRUE || returnLength != sizeof(FRAMEHDR)) {
dprintf(
"stackTrace: --- could not read frame %08lx\n",
frameAddress
);
return;
}
//
// Do we care about the frame?
//
switch(frame.dwSig) {
case SIG_CALL:
callSeen = TRUE;
stackCall(
(ULONG_PTR) frameAddress
);
break;
case SIG_TERM:
if (!callSeen || (callSeen && Verbose)) {
stackTerm(
(ULONG_PTR) frameAddress
);
}
} // switch
//
// Next
//
frameAddress += frame.dwLen;
}
}