dsdebug.c revision 303975
1178431Sscf/****************************************************************************** 2178431Sscf * 3178431Sscf * Module Name: dsdebug - Parser/Interpreter interface - debugging 4178431Sscf * 5178431Sscf *****************************************************************************/ 6178431Sscf 7178431Sscf/* 8178431Sscf * Copyright (C) 2000 - 2016, Intel Corp. 9178431Sscf * All rights reserved. 10178431Sscf * 11178431Sscf * Redistribution and use in source and binary forms, with or without 12178431Sscf * modification, are permitted provided that the following conditions 13178431Sscf * are met: 14178431Sscf * 1. Redistributions of source code must retain the above copyright 15178431Sscf * notice, this list of conditions, and the following disclaimer, 16178431Sscf * without modification. 17178431Sscf * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18178431Sscf * substantially similar to the "NO WARRANTY" disclaimer below 19178431Sscf * ("Disclaimer") and any redistribution must be conditioned upon 20178431Sscf * including a substantially similar Disclaimer requirement for further 21178431Sscf * binary redistribution. 22178431Sscf * 3. Neither the names of the above-listed copyright holders nor the names 23178431Sscf * of any contributors may be used to endorse or promote products derived 24178431Sscf * from this software without specific prior written permission. 25178431Sscf * 26178431Sscf * Alternatively, this software may be distributed under the terms of the 27178431Sscf * GNU General Public License ("GPL") version 2 as published by the Free 28178431Sscf * Software Foundation. 29178431Sscf * 30178431Sscf * NO WARRANTY 31178431Sscf * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32178431Sscf * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33178431Sscf * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34178431Sscf * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35178431Sscf * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36178431Sscf * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37178431Sscf * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38178431Sscf * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39178431Sscf * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40178431Sscf * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41178431Sscf * POSSIBILITY OF SUCH DAMAGES. 42178431Sscf */ 43178431Sscf 44178431Sscf#include <contrib/dev/acpica/include/acpi.h> 45178431Sscf#include <contrib/dev/acpica/include/accommon.h> 46178431Sscf#include <contrib/dev/acpica/include/acdispat.h> 47178431Sscf#include <contrib/dev/acpica/include/acnamesp.h> 48178431Sscf#include <contrib/dev/acpica/include/acdisasm.h> 49178431Sscf#include <contrib/dev/acpica/include/acinterp.h> 50178431Sscf 51178431Sscf 52178431Sscf#define _COMPONENT ACPI_DISPATCHER 53178431Sscf ACPI_MODULE_NAME ("dsdebug") 54178431Sscf 55178431Sscf 56178431Sscf#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) 57178431Sscf 58178431Sscf/* Local prototypes */ 59178431Sscf 60178431Sscfstatic void 61178431SscfAcpiDsPrintNodePathname ( 62178431Sscf ACPI_NAMESPACE_NODE *Node, 63178431Sscf const char *Message); 64178431Sscf 65178431Sscf 66178431Sscf/******************************************************************************* 67178431Sscf * 68178431Sscf * FUNCTION: AcpiDsPrintNodePathname 69178431Sscf * 70178431Sscf * PARAMETERS: Node - Object 71178431Sscf * Message - Prefix message 72178431Sscf * 73178431Sscf * DESCRIPTION: Print an object's full namespace pathname 74178431Sscf * Manages allocation/freeing of a pathname buffer 75178431Sscf * 76178431Sscf ******************************************************************************/ 77178431Sscf 78178431Sscfstatic void 79178431SscfAcpiDsPrintNodePathname ( 80178431Sscf ACPI_NAMESPACE_NODE *Node, 81178431Sscf const char *Message) 82178431Sscf{ 83178431Sscf ACPI_BUFFER Buffer; 84178431Sscf ACPI_STATUS Status; 85178431Sscf 86178431Sscf 87178431Sscf ACPI_FUNCTION_TRACE (DsPrintNodePathname); 88178431Sscf 89178431Sscf if (!Node) 90178431Sscf { 91178431Sscf ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[NULL NAME]")); 92178431Sscf return_VOID; 93178431Sscf } 94178431Sscf 95178431Sscf /* Convert handle to full pathname and print it (with supplied message) */ 96178431Sscf 97178431Sscf Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 98178431Sscf 99178431Sscf Status = AcpiNsHandleToPathname (Node, &Buffer, TRUE); 100178431Sscf if (ACPI_SUCCESS (Status)) 101178431Sscf { 102178431Sscf if (Message) 103178431Sscf { 104178431Sscf ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "%s ", Message)); 105178431Sscf } 106178431Sscf 107178431Sscf ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[%s] (Node %p)", 108178431Sscf (char *) Buffer.Pointer, Node)); 109178431Sscf ACPI_FREE (Buffer.Pointer); 110178431Sscf } 111178431Sscf 112178431Sscf return_VOID; 113178431Sscf} 114178431Sscf 115178431Sscf 116178431Sscf/******************************************************************************* 117178431Sscf * 118178431Sscf * FUNCTION: AcpiDsDumpMethodStack 119178431Sscf * 120178431Sscf * PARAMETERS: Status - Method execution status 121178431Sscf * WalkState - Current state of the parse tree walk 122178431Sscf * Op - Executing parse op 123178431Sscf * 124178431Sscf * RETURN: None 125178431Sscf * 126178431Sscf * DESCRIPTION: Called when a method has been aborted because of an error. 127178431Sscf * Dumps the method execution stack. 128178431Sscf * 129178431Sscf ******************************************************************************/ 130178431Sscf 131178431Sscfvoid 132178431SscfAcpiDsDumpMethodStack ( 133178431Sscf ACPI_STATUS Status, 134178431Sscf ACPI_WALK_STATE *WalkState, 135178431Sscf ACPI_PARSE_OBJECT *Op) 136178431Sscf{ 137178431Sscf ACPI_PARSE_OBJECT *Next; 138178431Sscf ACPI_THREAD_STATE *Thread; 139178431Sscf ACPI_WALK_STATE *NextWalkState; 140178431Sscf ACPI_NAMESPACE_NODE *PreviousMethod = NULL; 141178431Sscf ACPI_OPERAND_OBJECT *MethodDesc; 142178431Sscf 143178431Sscf 144178431Sscf ACPI_FUNCTION_TRACE (DsDumpMethodStack); 145178431Sscf 146178431Sscf /* Ignore control codes, they are not errors */ 147178431Sscf 148178431Sscf if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL) 149178431Sscf { 150178431Sscf return_VOID; 151178431Sscf } 152178431Sscf 153178431Sscf /* We may be executing a deferred opcode */ 154178431Sscf 155178431Sscf if (WalkState->DeferredNode) 156178431Sscf { 157178431Sscf ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 158178431Sscf "Executing subtree for Buffer/Package/Region\n")); 159178431Sscf return_VOID; 160178431Sscf } 161178431Sscf 162178431Sscf /* 163178431Sscf * If there is no Thread, we are not actually executing a method. 164178431Sscf * This can happen when the iASL compiler calls the interpreter 165178431Sscf * to perform constant folding. 166178431Sscf */ 167178431Sscf Thread = WalkState->Thread; 168178431Sscf if (!Thread) 169178431Sscf { 170178431Sscf return_VOID; 171178431Sscf } 172178431Sscf 173178431Sscf /* Display exception and method name */ 174178431Sscf 175178431Sscf ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 176178431Sscf "\n**** Exception %s during execution of method ", 177178431Sscf AcpiFormatException (Status))); 178178431Sscf 179178431Sscf AcpiDsPrintNodePathname (WalkState->MethodNode, NULL); 180178431Sscf 181178431Sscf /* Display stack of executing methods */ 182178431Sscf 183178431Sscf ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, 184178431Sscf "\n\nMethod Execution Stack:\n")); 185178431Sscf NextWalkState = Thread->WalkStateList; 186178431Sscf 187178431Sscf /* Walk list of linked walk states */ 188178431Sscf 189178431Sscf while (NextWalkState) 190178431Sscf { 191178431Sscf MethodDesc = NextWalkState->MethodDesc; 192178431Sscf if (MethodDesc) 193178431Sscf { 194178431Sscf AcpiExStopTraceMethod ( 195178431Sscf (ACPI_NAMESPACE_NODE *) MethodDesc->Method.Node, 196178431Sscf MethodDesc, WalkState); 197178431Sscf } 198178431Sscf 199178431Sscf ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 200178431Sscf " Method [%4.4s] executing: ", 201178431Sscf AcpiUtGetNodeName (NextWalkState->MethodNode))); 202178431Sscf 203178431Sscf /* First method is the currently executing method */ 204178431Sscf 205178431Sscf if (NextWalkState == WalkState) 206178431Sscf { 207178431Sscf if (Op) 208178431Sscf { 209178431Sscf /* Display currently executing ASL statement */ 210178431Sscf 211178431Sscf Next = Op->Common.Next; 212178431Sscf Op->Common.Next = NULL; 213178431Sscf 214178431Sscf#ifdef ACPI_DISASSEMBLER 215178431Sscf AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX); 216178431Sscf#endif 217178431Sscf Op->Common.Next = Next; 218178431Sscf } 219178431Sscf } 220178431Sscf else 221178431Sscf { 222178431Sscf /* 223178431Sscf * This method has called another method 224178431Sscf * NOTE: the method call parse subtree is already deleted at 225178431Sscf * this point, so we cannot disassemble the method invocation. 226178431Sscf */ 227178431Sscf ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Call to method ")); 228178431Sscf AcpiDsPrintNodePathname (PreviousMethod, NULL); 229178431Sscf } 230178431Sscf 231178431Sscf PreviousMethod = NextWalkState->MethodNode; 232178431Sscf NextWalkState = NextWalkState->Next; 233178431Sscf ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "\n")); 234178431Sscf } 235 236 return_VOID; 237} 238 239#else 240 241void 242AcpiDsDumpMethodStack ( 243 ACPI_STATUS Status, 244 ACPI_WALK_STATE *WalkState, 245 ACPI_PARSE_OBJECT *Op) 246{ 247 return; 248} 249 250#endif 251