372 lines
6.2 KiB
C
372 lines
6.2 KiB
C
/*++
|
||
|
||
Copyright (c) 1997 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
scope.c
|
||
|
||
Abstract:
|
||
|
||
The scope portion of the parser
|
||
|
||
Author:
|
||
|
||
Michael Tsang
|
||
Stephane Plante
|
||
|
||
Environment:
|
||
|
||
Any
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "pch.h"
|
||
UCHAR GlobalIndent[80];
|
||
|
||
PUNASM_AMLTERM
|
||
ScopeFindExtendedOpcode(
|
||
IN PSTACK *Stack
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function looks in the extended opcode table for the matching
|
||
AML term
|
||
|
||
Arguments:
|
||
|
||
Stack - The current thread of execution
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS status;
|
||
PUNASM_SCOPE localScope;
|
||
ULONG index = 0;
|
||
PUNASM_OPCODEMAP opcodeMap;
|
||
|
||
ASSERT( Stack != NULL && *Stack != NULL );
|
||
|
||
//
|
||
// Step 1: Find the top of the stack
|
||
//
|
||
status = StackTop( Stack, &localScope );
|
||
if (!NT_SUCCESS(status)) {
|
||
|
||
return NULL;
|
||
|
||
}
|
||
|
||
//
|
||
// Step 2: Loop Forever
|
||
//
|
||
while (1) {
|
||
|
||
//
|
||
// Step 2.1: Get the entry out of the extended opcode table
|
||
//
|
||
opcodeMap = &(ExOpcodeTable[index]);
|
||
|
||
//
|
||
// Step 2.2: Make sure that we haven't crossed the end
|
||
//
|
||
if (opcodeMap->OpCode == 0) {
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
//
|
||
// Step 2.3: Did we find what we where looking for?
|
||
//
|
||
if (opcodeMap->OpCode == *(localScope->CurrentByte) ) {
|
||
|
||
return opcodeMap->AmlTerm;
|
||
|
||
}
|
||
|
||
//
|
||
// Step 2.4: No?
|
||
//
|
||
index++;
|
||
|
||
}
|
||
|
||
//
|
||
// Step 3: Failure
|
||
//
|
||
return NULL;
|
||
}
|
||
|
||
#if 0
|
||
NTSTATUS
|
||
ScopeFindLocalScope(
|
||
IN PSTACK *Stack,
|
||
OUT PUNASM_SCOPE *LocalScope,
|
||
OUT PUNASM_SCOPE *RootScope
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function is a helper function. It simply grabs the top and bottom
|
||
of the stack and returns them.
|
||
|
||
This is a macro
|
||
|
||
Arguments:
|
||
|
||
Stack - The top of the stack
|
||
LocalScope - Where we want the top of stack
|
||
RootScope - Where we want the bottom of stack
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS status;
|
||
|
||
ASSERT( Stack != NULL && *Stack != NULL );
|
||
ASSERT( LocalScope != NULL );
|
||
ASSERT( RootScope != NULL );
|
||
|
||
//
|
||
// Step 1: Grab the local scope
|
||
//
|
||
status = StackTop( Stack, LocalScope );
|
||
if (!NT_SUCCESS(status)) {
|
||
|
||
return status;
|
||
|
||
}
|
||
|
||
//
|
||
// Step 2: Grab the root
|
||
//
|
||
status = StackRoot( Stack, RootScope );
|
||
if (!(NT_SUCCESS(status)) {
|
||
|
||
return status;
|
||
|
||
}
|
||
}
|
||
#endif
|
||
|
||
NTSTATUS
|
||
ScopeParser(
|
||
IN PUCHAR Start,
|
||
IN ULONG Length,
|
||
IN ULONG BaseAddress,
|
||
IN ULONG IndentLevel
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine arranges things so that the supplied bytes can be parsed
|
||
|
||
Arguments:
|
||
|
||
Start - Pointer to the first byte to parse
|
||
Length - Number of Bytes to parse
|
||
BaseAddress - Used for calculating memory location of instruction
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS status;
|
||
PSTACK stack;
|
||
PUNASM_SCOPE scope;
|
||
|
||
//
|
||
// Setup the global indent
|
||
//
|
||
IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel );
|
||
MEMORY_SET( GlobalIndent, ' ', IndentLevel );
|
||
GlobalIndent[IndentLevel] = '\0';
|
||
|
||
//
|
||
// Step 1: Obtain a stack
|
||
//
|
||
status = StackAllocate( &stack, sizeof(UNASM_SCOPE) );
|
||
if (!NT_SUCCESS(status)) {
|
||
|
||
return status;
|
||
|
||
} else if (stack == NULL) {
|
||
|
||
return STATUS_FAIL_CHECK;
|
||
|
||
}
|
||
|
||
//
|
||
// Step 2: Setup the root scope
|
||
//
|
||
status = StackPush( &stack, &scope );
|
||
if (!NT_SUCCESS(status)) {
|
||
|
||
return status;
|
||
|
||
}
|
||
scope->CurrentByte = Start;
|
||
scope->LastByte = Start + Length - 1;
|
||
scope->IndentLevel = 0;
|
||
scope->BaseAddress = BaseAddress;
|
||
|
||
//
|
||
// Step 3: Initialize the string stack
|
||
//
|
||
status = StringStackAllocate( &(scope->StringStack) );
|
||
if (!NT_SUCCESS(status)) {
|
||
|
||
return status;
|
||
|
||
}
|
||
status = StringStackAllocate( &(scope->ParseStack) );
|
||
if (!NT_SUCCESS(status)) {
|
||
|
||
return status;
|
||
|
||
}
|
||
//
|
||
// Step 4: Parse the scope
|
||
//
|
||
status = ParseScope( &stack );
|
||
if (NT_SUCCESS(status)) {
|
||
|
||
status = StackRoot( &stack, &scope );
|
||
if (!NT_SUCCESS(status)) {
|
||
|
||
return status;
|
||
|
||
}
|
||
StringStackFree( &(scope->StringStack) );
|
||
StringStackFree( &(scope->ParseStack) );
|
||
StackPop( &stack );
|
||
StackFree( &stack );
|
||
|
||
}
|
||
|
||
//
|
||
// Step 5: Done
|
||
//
|
||
return status;
|
||
}
|
||
|
||
NTSTATUS
|
||
ScopePrint(
|
||
IN PSTACK *Stack
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This prints and clears the string in the current scope
|
||
|
||
Arguments:
|
||
|
||
The current thread's stack
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS status;
|
||
PUNASM_SCOPE scope;
|
||
PUNASM_SCOPE root;
|
||
PUCHAR buffer;
|
||
|
||
//
|
||
// Step 1: Get the local scope
|
||
//
|
||
ScopeFindLocalScope( Stack, &scope, &root, status );
|
||
|
||
//
|
||
// Step 2: Allocate a buffer to print spaces to
|
||
//
|
||
buffer = MEMORY_ALLOCATE( scope->IndentLevel + 11 );
|
||
if (buffer == NULL) {
|
||
|
||
return STATUS_INSUFFICIENT_RESOURCES;
|
||
|
||
}
|
||
|
||
//
|
||
// Step 3: Check to see if there is an indent level
|
||
//
|
||
if (scope->IndentLevel) {
|
||
|
||
//
|
||
// Step 3.1.1: Print some spaces to that buffer
|
||
//
|
||
STRING_PRINT(
|
||
buffer,
|
||
"%s%08x %*s",
|
||
GlobalIndent,
|
||
scope->TermByte + root->BaseAddress,
|
||
scope->IndentLevel,
|
||
""
|
||
);
|
||
|
||
} else {
|
||
|
||
//
|
||
// Step 3.2.1: Print just the address
|
||
//
|
||
STRING_PRINT(
|
||
buffer,
|
||
"%s%08x ",
|
||
GlobalIndent,
|
||
scope->TermByte + root->BaseAddress
|
||
);
|
||
|
||
}
|
||
|
||
//
|
||
// Step 4 Show it to the user
|
||
//
|
||
PRINTF( "%s", buffer );
|
||
|
||
//
|
||
// Step 5: Free the memory
|
||
//
|
||
MEMORY_FREE( buffer );
|
||
|
||
//
|
||
// Step 6: Grab the root stack
|
||
//
|
||
status = StackRoot( Stack, &scope );
|
||
if (!NT_SUCCESS(status)) {
|
||
|
||
return status;
|
||
|
||
}
|
||
|
||
//
|
||
// Step 7: Show the user the buffer
|
||
//
|
||
StringStackPush( &(scope->StringStack), 1, "\0" );
|
||
PRINTF( "%s", scope->StringStack->Stack );
|
||
StringStackClear( &(scope->StringStack) );
|
||
|
||
//
|
||
// Step 8: Done
|
||
//
|
||
return status;
|
||
}
|
||
|