# Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
# For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
from __future__ import print_function
from gdb.printing import PrettyPrinter, register_pretty_printer
import gdb
import uuid
class MMFSR_bits:
IACCVIOL = 0
DACCVIOL = 1
MUNSTKERR = 3
MSTKERR = 4
MMARVALID = 7
class CrashDump(gdb.Command):
"""Prints the ListNode from our example in a nice format!"""
def __init__(self):
super(CrashDump, self).__init__(
"crash_dump", gdb.COMMAND_USER
)
def _crash_dump(self, val=None):
"""
"""
value=gdb.parse_and_eval("*0xE000ED28");
# print(type(value), gdb.parse_and_eval(value))
print(value)
if value & 1 << MMFSR_bits.MMARVALID:
print("MMAR holds proper address")
if value & 1 << MMFSR_bits.MSTKERR:
print("stacking for an exception entry has caused one or more access violations.")
if value & 1 << MMFSR_bits.MUNSTKERR:
print("unstack for an exception return has caused one or more access violations.")
if value & 1 << MMFSR_bits.DACCVIOL:
print("the processor attempted a load or store at a location that does not permit the operation.")
if value & 1 << MMFSR_bits.IACCVIOL:
print("the processor attempted an instruction fetch from a location that does not permit execution.")
# TODO check psp vs msp by lr young bits
psp=gdb.parse_and_eval("$psp")
frame=gdb.parse_and_eval("*(syslog_exception_stack_frame_t*)$psp")
print("Privileged Stack Pointer: {}".format(frame))
if frame["psr"] & (1<<9):
print("On exception entry CPU aligns new SP to 8 bytes so sometimes it needs to push additional 4 bytes to make it happen.")
psp+=4
else:
print("normal stack pointer")
gdb.execute("set $r0={}".format(frame["r0"]))
gdb.execute("set $r1={}".format(frame["r1"]))
gdb.execute("set $r2={}".format(frame["r2"]))
gdb.execute("set $r3={}".format(frame["r3"]))
gdb.execute("set $r12={}".format(frame["r12"]))
gdb.execute("set $lr={}".format(frame["lr"]))
gdb.execute("set $pc={}".format(frame["pc"]))
gdb.execute("set $psr={}".format(frame["psr"]))
gdb.execute("set $sp={}".format(psp))
gdb.execute("bt")
return val
def complete(self, text, word):
# We expect the argument passed to be a symbol so fallback to the
# internal tab-completion handler for symbols
return gdb.COMPLETE_SYMBOL
def invoke(self, args, from_tty):
print("Args Passed: %s" % args)
print(self._crash_dump())
CrashDump()