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;
|
|||
|
}
|
|||
|
|