/*++ 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; }