2021-01-13 09:34:25 +01:00
|
|
|
############################################################################
|
|
|
|
# tools/esp32/backtrace.gdbscript
|
|
|
|
#
|
|
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
|
|
# this work for additional information regarding copyright ownership. The
|
|
|
|
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
|
|
# "License"); you may not use this file except in compliance with the
|
|
|
|
# License. You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
|
|
# License for the specific language governing permissions and limitations
|
|
|
|
# under the License.
|
|
|
|
#
|
|
|
|
############################################################################
|
|
|
|
|
|
|
|
# Usage:
|
|
|
|
#
|
2021-01-21 05:57:54 +01:00
|
|
|
# (gdb) esp32_bt <pc> <return address (a0)> <sp (a1)>
|
|
|
|
#
|
|
|
|
# Example 1:
|
|
|
|
#
|
|
|
|
# -------
|
|
|
|
# xtensa_btdump: Backtrace0: 400d82a3:3ffdec60
|
|
|
|
# xtensa_btdump: Backtrace1: 400d82ff:3ffdec80
|
|
|
|
# -------
|
|
|
|
# (gdb) esp32_bt 0x400d82ff 0x400d82a3 0x3ffdec60
|
|
|
|
# -------
|
|
|
|
#
|
|
|
|
# Example 2:
|
|
|
|
#
|
2021-01-13 09:34:25 +01:00
|
|
|
# -------
|
|
|
|
# xtensa_registerdump: PC: 400d5775 PS: 00060e33
|
|
|
|
# xtensa_registerdump: A0: 800d504c A1: 3ffd8080 A2: 3ffdfb28 A3: 00000001
|
|
|
|
# -------
|
|
|
|
# (gdb) esp32_bt 0x400d5775 0x800d504c 0x3ffd8080
|
|
|
|
# -------
|
|
|
|
#
|
2021-01-21 05:57:54 +01:00
|
|
|
# Caveats:
|
|
|
|
#
|
|
|
|
# This doesn't work if the specified register values are already
|
|
|
|
# inconsistent with the frames on the stack. It's usually the case
|
|
|
|
# when xtensa_registerdump saved the state by itself using
|
|
|
|
# xtensa_context_save.
|
|
|
|
#
|
2021-01-13 09:34:25 +01:00
|
|
|
# References:
|
|
|
|
#
|
|
|
|
# Xtensa(R) Instruction Set Architecture (ISA) Reference Manual
|
|
|
|
# 4.7.1.4 Call, Entry, and Return Mechanism
|
|
|
|
# 4.7.1.5 Windowed Procedure-Call Protocol
|
|
|
|
|
|
|
|
define esp32_bt
|
|
|
|
set $pc = $arg0
|
|
|
|
set $a0 = $arg1
|
|
|
|
set $a1 = $arg2
|
|
|
|
set $pc_topbits = (int)$pc & 0xc0000000
|
|
|
|
# The return address from xtensa_sig_deliver to _xtensa_sig_trampoline
|
|
|
|
set $sig_tramp_ra = (int)(_xtensa_sig_trampoline + 2 * 3)
|
|
|
|
print/a $pc
|
|
|
|
while (1)
|
|
|
|
# Note: "- 3" to workaround the case where "call" is
|
|
|
|
# the last instruction in the calling function.
|
|
|
|
set $next_pc = (($a0 & 0x3fffffff) | $pc_topbits) - 3
|
|
|
|
print/a $next_pc
|
|
|
|
if ($a0 == $sig_tramp_ra)
|
|
|
|
# A special logic for xtensa_sig_deliver
|
|
|
|
|
|
|
|
print "--- SIGNAL ---"
|
|
|
|
|
|
|
|
# XXX SMP
|
|
|
|
set $tcb = (struct tcb_s *)g_readytorun.head
|
|
|
|
set $next_pc = $tcb.xcp.saved_pc
|
|
|
|
print/a $next_pc
|
|
|
|
|
|
|
|
# XXX local var offset assumption
|
|
|
|
set $regs = (int *)$a1
|
|
|
|
|
|
|
|
# Note: REG_A0 == 2
|
|
|
|
# Note: REG_A1 == 3
|
|
|
|
set $next_a0 = $regs[2]
|
|
|
|
set $next_a1 = $regs[3]
|
|
|
|
else
|
|
|
|
set $next_bsa = (int *)($a1 - 16)
|
|
|
|
set $next_a0 = $next_bsa[0]
|
|
|
|
set $next_a1 = $next_bsa[1]
|
|
|
|
end
|
|
|
|
if ($next_a0 == 0)
|
|
|
|
# Xtensa(R) Instruction Set Architecture (ISA) Reference Manual
|
|
|
|
# 8.1.9 Stack Initialization
|
|
|
|
# "The return address register (a0) for the first procedure
|
|
|
|
# on the stack must be explicitly set to zero."
|
|
|
|
loop_break
|
|
|
|
end
|
|
|
|
if ($next_a1 <= $a1)
|
|
|
|
print "stack went backward. corrupted?"
|
|
|
|
loop_break
|
|
|
|
end
|
|
|
|
set $a0 = $next_a0
|
|
|
|
set $a1 = $next_a1
|
|
|
|
end
|
|
|
|
end
|