1 /****************************************************************************** 2 * 3 * Module Name: dsdebug - Parser/Interpreter interface - debugging 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/acdispat.h> 47 #include <contrib/dev/acpica/include/acnamesp.h> 48 #include <contrib/dev/acpica/include/acdisasm.h> 49 #include <contrib/dev/acpica/include/acinterp.h> 50 51 52 #define _COMPONENT ACPI_DISPATCHER 53 ACPI_MODULE_NAME ("dsdebug") 54 55 56 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) 57 58 /* Local prototypes */ 59 60 static void 61 AcpiDsPrintNodePathname ( 62 ACPI_NAMESPACE_NODE *Node, 63 const char *Message); 64 65 66 /******************************************************************************* 67 * 68 * FUNCTION: AcpiDsPrintNodePathname 69 * 70 * PARAMETERS: Node - Object 71 * Message - Prefix message 72 * 73 * DESCRIPTION: Print an object's full namespace pathname 74 * Manages allocation/freeing of a pathname buffer 75 * 76 ******************************************************************************/ 77 78 static void 79 AcpiDsPrintNodePathname ( 80 ACPI_NAMESPACE_NODE *Node, 81 const char *Message) 82 { 83 ACPI_BUFFER Buffer; 84 ACPI_STATUS Status; 85 86 87 ACPI_FUNCTION_TRACE (DsPrintNodePathname); 88 89 if (!Node) 90 { 91 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[NULL NAME]")); 92 return_VOID; 93 } 94 95 /* Convert handle to full pathname and print it (with supplied message) */ 96 97 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 98 99 Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE); 100 if (ACPI_SUCCESS (Status)) 101 { 102 if (Message) 103 { 104 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "%s ", Message)); 105 } 106 107 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[%s] (Node %p)", 108 (char *) Buffer.Pointer, Node)); 109 ACPI_FREE (Buffer.Pointer); 110 } 111 112 return_VOID; 113 } 114 115 116 /******************************************************************************* 117 * 118 * FUNCTION: AcpiDsDumpMethodStack 119 * 120 * PARAMETERS: Status - Method execution status 121 * WalkState - Current state of the parse tree walk 122 * Op - Executing parse op 123 * 124 * RETURN: None 125 * 126 * DESCRIPTION: Called when a method has been aborted because of an error. 127 * Dumps the method execution stack. 128 * 129 ******************************************************************************/ 130 131 void 132 AcpiDsDumpMethodStack ( 133 ACPI_STATUS Status, 134 ACPI_WALK_STATE *WalkState, 135 ACPI_PARSE_OBJECT *Op) 136 { 137 ACPI_PARSE_OBJECT *Next; 138 ACPI_THREAD_STATE *Thread; 139 ACPI_WALK_STATE *NextWalkState; 140 ACPI_NAMESPACE_NODE *PreviousMethod = NULL; 141 ACPI_OPERAND_OBJECT *MethodDesc; 142 143 144 ACPI_FUNCTION_TRACE (DsDumpMethodStack); 145 146 /* Ignore control codes, they are not errors */ 147 148 if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL) 149 { 150 return_VOID; 151 } 152 153 /* We may be executing a deferred opcode */ 154 155 if (WalkState->DeferredNode) 156 { 157 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 158 "Executing subtree for Buffer/Package/Region\n")); 159 return_VOID; 160 } 161 162 /* 163 * If there is no Thread, we are not actually executing a method. 164 * This can happen when the iASL compiler calls the interpreter 165 * to perform constant folding. 166 */ 167 Thread = WalkState->Thread; 168 if (!Thread) 169 { 170 return_VOID; 171 } 172 173 /* Display exception and method name */ 174 175 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 176 "\n**** Exception %s during execution of method ", 177 AcpiFormatException (Status))); 178 AcpiDsPrintNodePathname (WalkState->MethodNode, NULL); 179 180 /* Display stack of executing methods */ 181 182 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, 183 "\n\nMethod Execution Stack:\n")); 184 NextWalkState = Thread->WalkStateList; 185 186 /* Walk list of linked walk states */ 187 188 while (NextWalkState) 189 { 190 MethodDesc = NextWalkState->MethodDesc; 191 if (MethodDesc) 192 { 193 AcpiExStopTraceMethod ( 194 (ACPI_NAMESPACE_NODE *) MethodDesc->Method.Node, 195 MethodDesc, WalkState); 196 } 197 198 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 199 " Method [%4.4s] executing: ", 200 AcpiUtGetNodeName (NextWalkState->MethodNode))); 201 202 /* First method is the currently executing method */ 203 204 if (NextWalkState == WalkState) 205 { 206 if (Op) 207 { 208 /* Display currently executing ASL statement */ 209 210 Next = Op->Common.Next; 211 Op->Common.Next = NULL; 212 213 #ifdef ACPI_DISASSEMBLER 214 AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX); 215 #endif 216 Op->Common.Next = Next; 217 } 218 } 219 else 220 { 221 /* 222 * This method has called another method 223 * NOTE: the method call parse subtree is already deleted at this 224 * point, so we cannot disassemble the method invocation. 225 */ 226 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Call to method ")); 227 AcpiDsPrintNodePathname (PreviousMethod, NULL); 228 } 229 230 PreviousMethod = NextWalkState->MethodNode; 231 NextWalkState = NextWalkState->Next; 232 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "\n")); 233 } 234 235 return_VOID; 236 } 237 238 #else 239 240 void 241 AcpiDsDumpMethodStack ( 242 ACPI_STATUS Status, 243 ACPI_WALK_STATE *WalkState, 244 ACPI_PARSE_OBJECT *Op) 245 { 246 return; 247 } 248 249 #endif 250