windows-nt/Source/XPSP1/NT/base/busdrv/acpi/tools/unasm/scope.c

372 lines
6.2 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
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;
}