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