2018-03-15 02:13:07 +03:00
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2015-07-23 07:52:46 +03:00
/******************************************************************************
*
* Module Name : dsdebug - Parser / Interpreter interface - debugging
*
2021-01-15 21:48:25 +03:00
* Copyright ( C ) 2000 - 2021 , Intel Corp .
2015-07-23 07:52:46 +03:00
*
2018-03-15 02:13:07 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-07-23 07:52:46 +03:00
# include <acpi/acpi.h>
# include "accommon.h"
# include "acdispat.h"
# include "acnamesp.h"
# ifdef ACPI_DISASSEMBLER
# include "acdisasm.h"
# endif
2015-07-23 07:52:59 +03:00
# include "acinterp.h"
2015-07-23 07:52:46 +03:00
# define _COMPONENT ACPI_DISPATCHER
ACPI_MODULE_NAME ( " dsdebug " )
# if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
/* Local prototypes */
static void
acpi_ds_print_node_pathname ( struct acpi_namespace_node * node ,
const char * message ) ;
/*******************************************************************************
*
* FUNCTION : acpi_ds_print_node_pathname
*
* PARAMETERS : node - Object
* message - Prefix message
*
* DESCRIPTION : Print an object ' s full namespace pathname
* Manages allocation / freeing of a pathname buffer
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void
acpi_ds_print_node_pathname ( struct acpi_namespace_node * node ,
const char * message )
{
struct acpi_buffer buffer ;
acpi_status status ;
ACPI_FUNCTION_TRACE ( ds_print_node_pathname ) ;
if ( ! node ) {
ACPI_DEBUG_PRINT_RAW ( ( ACPI_DB_DISPATCH , " [NULL NAME] " ) ) ;
return_VOID ;
}
/* Convert handle to full pathname and print it (with supplied message) */
buffer . length = ACPI_ALLOCATE_LOCAL_BUFFER ;
2015-08-25 05:30:41 +03:00
status = acpi_ns_handle_to_pathname ( node , & buffer , TRUE ) ;
2015-07-23 07:52:46 +03:00
if ( ACPI_SUCCESS ( status ) ) {
if ( message ) {
ACPI_DEBUG_PRINT_RAW ( ( ACPI_DB_DISPATCH , " %s " ,
message ) ) ;
}
ACPI_DEBUG_PRINT_RAW ( ( ACPI_DB_DISPATCH , " [%s] (Node %p) " ,
( char * ) buffer . pointer , node ) ) ;
ACPI_FREE ( buffer . pointer ) ;
}
return_VOID ;
}
/*******************************************************************************
*
* FUNCTION : acpi_ds_dump_method_stack
*
* PARAMETERS : status - Method execution status
* walk_state - Current state of the parse tree walk
* op - Executing parse op
*
* RETURN : None
*
* DESCRIPTION : Called when a method has been aborted because of an error .
* Dumps the method execution stack .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void
acpi_ds_dump_method_stack ( acpi_status status ,
struct acpi_walk_state * walk_state ,
union acpi_parse_object * op )
{
union acpi_parse_object * next ;
struct acpi_thread_state * thread ;
struct acpi_walk_state * next_walk_state ;
struct acpi_namespace_node * previous_method = NULL ;
2015-07-23 07:52:53 +03:00
union acpi_operand_object * method_desc ;
2015-07-23 07:52:46 +03:00
ACPI_FUNCTION_TRACE ( ds_dump_method_stack ) ;
/* Ignore control codes, they are not errors */
2021-01-15 21:48:19 +03:00
if ( ACPI_CNTL_EXCEPTION ( status ) ) {
2015-07-23 07:52:46 +03:00
return_VOID ;
}
/* We may be executing a deferred opcode */
if ( walk_state - > deferred_node ) {
ACPI_DEBUG_PRINT ( ( ACPI_DB_DISPATCH ,
" Executing subtree for Buffer/Package/Region \n " ) ) ;
return_VOID ;
}
/*
* If there is no Thread , we are not actually executing a method .
* This can happen when the iASL compiler calls the interpreter
* to perform constant folding .
*/
thread = walk_state - > thread ;
if ( ! thread ) {
return_VOID ;
}
/* Display exception and method name */
ACPI_DEBUG_PRINT ( ( ACPI_DB_DISPATCH ,
" \n **** Exception %s during execution of method " ,
acpi_format_exception ( status ) ) ) ;
2015-12-29 08:54:36 +03:00
2015-07-23 07:52:46 +03:00
acpi_ds_print_node_pathname ( walk_state - > method_node , NULL ) ;
/* Display stack of executing methods */
ACPI_DEBUG_PRINT_RAW ( ( ACPI_DB_DISPATCH ,
" \n \n Method Execution Stack: \n " ) ) ;
next_walk_state = thread - > walk_state_list ;
/* Walk list of linked walk states */
while ( next_walk_state ) {
2015-07-23 07:52:53 +03:00
method_desc = next_walk_state - > method_desc ;
2015-07-23 07:52:59 +03:00
if ( method_desc ) {
acpi_ex_stop_trace_method ( ( struct acpi_namespace_node * )
method_desc - > method . node ,
method_desc , walk_state ) ;
2015-07-23 07:52:53 +03:00
}
2015-07-23 07:52:46 +03:00
ACPI_DEBUG_PRINT ( ( ACPI_DB_DISPATCH ,
" Method [%4.4s] executing: " ,
acpi_ut_get_node_name ( next_walk_state - >
method_node ) ) ) ;
/* First method is the currently executing method */
if ( next_walk_state = = walk_state ) {
if ( op ) {
/* Display currently executing ASL statement */
next = op - > common . next ;
op - > common . next = NULL ;
# ifdef ACPI_DISASSEMBLER
2018-06-01 22:06:42 +03:00
if ( walk_state - > method_node ! =
acpi_gbl_root_node ) {
/* More verbose if not module-level code */
acpi_os_printf ( " Failed at " ) ;
acpi_dm_disassemble ( next_walk_state , op ,
ACPI_UINT32_MAX ) ;
}
2015-07-23 07:52:46 +03:00
# endif
op - > common . next = next ;
}
} else {
/*
* This method has called another method
2015-12-29 08:54:36 +03:00
* NOTE : the method call parse subtree is already deleted at
* this point , so we cannot disassemble the method invocation .
2015-07-23 07:52:46 +03:00
*/
ACPI_DEBUG_PRINT_RAW ( ( ACPI_DB_DISPATCH ,
" Call to method " ) ) ;
acpi_ds_print_node_pathname ( previous_method , NULL ) ;
}
previous_method = next_walk_state - > method_node ;
next_walk_state = next_walk_state - > next ;
ACPI_DEBUG_PRINT_RAW ( ( ACPI_DB_DISPATCH , " \n " ) ) ;
}
return_VOID ;
}
# else
void
acpi_ds_dump_method_stack ( acpi_status status ,
struct acpi_walk_state * walk_state ,
union acpi_parse_object * op )
{
return ;
}
# endif