Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

371 lines
6.2 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. scope.c
  5. Abstract:
  6. The scope portion of the parser
  7. Author:
  8. Michael Tsang
  9. Stephane Plante
  10. Environment:
  11. Any
  12. Revision History:
  13. --*/
  14. #include "pch.h"
  15. UCHAR GlobalIndent[80];
  16. PUNASM_AMLTERM
  17. ScopeFindExtendedOpcode(
  18. IN PSTACK *Stack
  19. )
  20. /*++
  21. Routine Description:
  22. This function looks in the extended opcode table for the matching
  23. AML term
  24. Arguments:
  25. Stack - The current thread of execution
  26. Return Value:
  27. None
  28. --*/
  29. {
  30. NTSTATUS status;
  31. PUNASM_SCOPE localScope;
  32. ULONG index = 0;
  33. PUNASM_OPCODEMAP opcodeMap;
  34. ASSERT( Stack != NULL && *Stack != NULL );
  35. //
  36. // Step 1: Find the top of the stack
  37. //
  38. status = StackTop( Stack, &localScope );
  39. if (!NT_SUCCESS(status)) {
  40. return NULL;
  41. }
  42. //
  43. // Step 2: Loop Forever
  44. //
  45. while (1) {
  46. //
  47. // Step 2.1: Get the entry out of the extended opcode table
  48. //
  49. opcodeMap = &(ExOpcodeTable[index]);
  50. //
  51. // Step 2.2: Make sure that we haven't crossed the end
  52. //
  53. if (opcodeMap->OpCode == 0) {
  54. break;
  55. }
  56. //
  57. // Step 2.3: Did we find what we where looking for?
  58. //
  59. if (opcodeMap->OpCode == *(localScope->CurrentByte) ) {
  60. return opcodeMap->AmlTerm;
  61. }
  62. //
  63. // Step 2.4: No?
  64. //
  65. index++;
  66. }
  67. //
  68. // Step 3: Failure
  69. //
  70. return NULL;
  71. }
  72. #if 0
  73. NTSTATUS
  74. ScopeFindLocalScope(
  75. IN PSTACK *Stack,
  76. OUT PUNASM_SCOPE *LocalScope,
  77. OUT PUNASM_SCOPE *RootScope
  78. )
  79. /*++
  80. Routine Description:
  81. This function is a helper function. It simply grabs the top and bottom
  82. of the stack and returns them.
  83. This is a macro
  84. Arguments:
  85. Stack - The top of the stack
  86. LocalScope - Where we want the top of stack
  87. RootScope - Where we want the bottom of stack
  88. Return Value:
  89. NTSTATUS
  90. --*/
  91. {
  92. NTSTATUS status;
  93. ASSERT( Stack != NULL && *Stack != NULL );
  94. ASSERT( LocalScope != NULL );
  95. ASSERT( RootScope != NULL );
  96. //
  97. // Step 1: Grab the local scope
  98. //
  99. status = StackTop( Stack, LocalScope );
  100. if (!NT_SUCCESS(status)) {
  101. return status;
  102. }
  103. //
  104. // Step 2: Grab the root
  105. //
  106. status = StackRoot( Stack, RootScope );
  107. if (!(NT_SUCCESS(status)) {
  108. return status;
  109. }
  110. }
  111. #endif
  112. NTSTATUS
  113. ScopeParser(
  114. IN PUCHAR Start,
  115. IN ULONG Length,
  116. IN ULONG BaseAddress,
  117. IN ULONG IndentLevel
  118. )
  119. /*++
  120. Routine Description:
  121. This routine arranges things so that the supplied bytes can be parsed
  122. Arguments:
  123. Start - Pointer to the first byte to parse
  124. Length - Number of Bytes to parse
  125. BaseAddress - Used for calculating memory location of instruction
  126. Return Value:
  127. NTSTATUS
  128. --*/
  129. {
  130. NTSTATUS status;
  131. PSTACK stack;
  132. PUNASM_SCOPE scope;
  133. //
  134. // Setup the global indent
  135. //
  136. IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel );
  137. MEMORY_SET( GlobalIndent, ' ', IndentLevel );
  138. GlobalIndent[IndentLevel] = '\0';
  139. //
  140. // Step 1: Obtain a stack
  141. //
  142. status = StackAllocate( &stack, sizeof(UNASM_SCOPE) );
  143. if (!NT_SUCCESS(status)) {
  144. return status;
  145. } else if (stack == NULL) {
  146. return STATUS_FAIL_CHECK;
  147. }
  148. //
  149. // Step 2: Setup the root scope
  150. //
  151. status = StackPush( &stack, &scope );
  152. if (!NT_SUCCESS(status)) {
  153. return status;
  154. }
  155. scope->CurrentByte = Start;
  156. scope->LastByte = Start + Length - 1;
  157. scope->IndentLevel = 0;
  158. scope->BaseAddress = BaseAddress;
  159. //
  160. // Step 3: Initialize the string stack
  161. //
  162. status = StringStackAllocate( &(scope->StringStack) );
  163. if (!NT_SUCCESS(status)) {
  164. return status;
  165. }
  166. status = StringStackAllocate( &(scope->ParseStack) );
  167. if (!NT_SUCCESS(status)) {
  168. return status;
  169. }
  170. //
  171. // Step 4: Parse the scope
  172. //
  173. status = ParseScope( &stack );
  174. if (NT_SUCCESS(status)) {
  175. status = StackRoot( &stack, &scope );
  176. if (!NT_SUCCESS(status)) {
  177. return status;
  178. }
  179. StringStackFree( &(scope->StringStack) );
  180. StringStackFree( &(scope->ParseStack) );
  181. StackPop( &stack );
  182. StackFree( &stack );
  183. }
  184. //
  185. // Step 5: Done
  186. //
  187. return status;
  188. }
  189. NTSTATUS
  190. ScopePrint(
  191. IN PSTACK *Stack
  192. )
  193. /*++
  194. Routine Description:
  195. This prints and clears the string in the current scope
  196. Arguments:
  197. The current thread's stack
  198. Return Value:
  199. NTSTATUS
  200. --*/
  201. {
  202. NTSTATUS status;
  203. PUNASM_SCOPE scope;
  204. PUNASM_SCOPE root;
  205. PUCHAR buffer;
  206. //
  207. // Step 1: Get the local scope
  208. //
  209. ScopeFindLocalScope( Stack, &scope, &root, status );
  210. //
  211. // Step 2: Allocate a buffer to print spaces to
  212. //
  213. buffer = MEMORY_ALLOCATE( scope->IndentLevel + 11 );
  214. if (buffer == NULL) {
  215. return STATUS_INSUFFICIENT_RESOURCES;
  216. }
  217. //
  218. // Step 3: Check to see if there is an indent level
  219. //
  220. if (scope->IndentLevel) {
  221. //
  222. // Step 3.1.1: Print some spaces to that buffer
  223. //
  224. STRING_PRINT(
  225. buffer,
  226. "%s%08x %*s",
  227. GlobalIndent,
  228. scope->TermByte + root->BaseAddress,
  229. scope->IndentLevel,
  230. ""
  231. );
  232. } else {
  233. //
  234. // Step 3.2.1: Print just the address
  235. //
  236. STRING_PRINT(
  237. buffer,
  238. "%s%08x ",
  239. GlobalIndent,
  240. scope->TermByte + root->BaseAddress
  241. );
  242. }
  243. //
  244. // Step 4 Show it to the user
  245. //
  246. PRINTF( "%s", buffer );
  247. //
  248. // Step 5: Free the memory
  249. //
  250. MEMORY_FREE( buffer );
  251. //
  252. // Step 6: Grab the root stack
  253. //
  254. status = StackRoot( Stack, &scope );
  255. if (!NT_SUCCESS(status)) {
  256. return status;
  257. }
  258. //
  259. // Step 7: Show the user the buffer
  260. //
  261. StringStackPush( &(scope->StringStack), 1, "\0" );
  262. PRINTF( "%s", scope->StringStack->Stack );
  263. StringStackClear( &(scope->StringStack) );
  264. //
  265. // Step 8: Done
  266. //
  267. return status;
  268. }