-
Notifications
You must be signed in to change notification settings - Fork 0
/
gdb-script
executable file
·129 lines (100 loc) · 5.36 KB
/
gdb-script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
target remote | openocd -c "source [find board/ek-tm4c123gxl.cfg]" -c "gdb_port pipe; log_output target/openocd.log"
monitor reset init
monitor halt
monitor arm semihosting enable
break main
stepi
set history filename target/gdb_history.log
# Ideally this all would go in a separate .gdbinit file but since we don't want
# to have to pass in the path to the common directory into this script, we'll
# just put the stuff here:
set print pretty on
py import duel
# ptype <var | type>
define reset
monitor reset halt
end
define current_exec
python print(gdb.objfiles()[0].filename)
end
# Uses descriptions/information sourced from here: https://interrupt.memfault.com/blog/cortex-m-fault-debug
define hardfault
python
def get_mem(addr):
return int(gdb.execute(f"x(0x{addr:X})", to_string = True).split("\t")[1].split(" ")[0].rstrip(), 0)
CFSR_ADDR = 0xE000ED28
HFSR_ADDR = 0xE000ED2C
# Configurable Fault Status Register
CFSR = get_mem(CFSR_ADDR)
# Usage Fault Status Register
UFSR = CFSR >> 16
# BusFault Status Register
BFSR = CFSR >> 8 & 0b11111111
# MemManage Status Register
MMFSR = CFSR & 0b11111111
# HardFault Status Register
HFSR = get_mem(HFSR_ADDR)
ufsr_faults = {
0: "UNDEFINSTR: Indicates an undefined instruction was executed. This can happen on exception exit if the stack got corrupted. A compiler may emit undefined instructions as well for code paths that should be unreachable.",
1: "INVSTATE: Indicates the processor has tried to execute an instruction with an invalid Execution Program Status Register (EPSR) value. Among other things the ESPR tracks whether or not the processor is in thumb mode state.",
2: "INVPC: Indicates an integrity check failure on EXC_RETURN. EXC_RETURN is the value branched to upon return from an exception. If this fault flag is set, it means a reserved EXC_RETURN value was used on exception exit.",
3: "NOCP: Indicates that a Cortex-M coprocessor instruction was issued but the coprocessor was disabled or not present.",
8: "UNALIGNED: Indicates an unaligned access operation occurred.",
9: "DIVBYZERO: Indicates a divide instruction was executed where the denominator was zero.",
}
bfsr_faults = {
0: "IBUSERR: ",
1: "PRECISERRR: Indicates that the instruction which was executing prior to exception entry triggered the fault.",
2: "IMPRECISERR: This flag is very important. It tells us whether or not the hardware was able to determine the exact location of the fault.",
3: "UNSTKERR: Indicates that a fault occurred trying to return from an exception.",
4: "STKERR: Indicates that a fault occurred during exception entry. Both are situations where the hardware is automatically saving state on the stack. One way this error may occur is if the stack in use overflows off the valid RAM address range while trying to service an exception.",
5: "LSPERR: Indicates that a fault occurred during lazy state preservation. Both are situations where the hardware is automatically saving state on the stack. One way this error may occur is if the stack in use overflows off the valid RAM address range while trying to service an exception.",
# 6: "Reserved",
7: "BFARVALID: Indicates that the Bus Fault Address Register (BFAR), a 32 bit register located at 0xE000ED38, holds the address which triggered the fault.",
}
mmfsr_faults = {
0: "IACCVIOL: Indicates that an attempt to execute an instruction triggered an MPU or Execute Never (XN) fault.",
1: "DACCVIOL: Indicates that a data access triggered the MemManage fault.",
# 2: "",
3: "MUNSTKERR: Indicates that a fault occurred while returning from an exception.",
4: "MSTKERR: Indicates that a MemManage fault occurred during exception entry.",
5: "MLSPERR: Indicates that a MemManage fault occurred during lazy state preservation.",
# 6: "",
7: "MMARVALID: Indicates that the MemManage Fault Address Register (MMFAR), a 32 bit register located at 0xE000ED34, holds the address which triggered the MemManage fault.",
}
hfsr_faults = {
1: "VECTTBL: Indicates a fault occurred because of an issue reading from an address in the vector table. This is pretty atypical but could happen if there is a bad address in the vector table and an unexpected interrupt fires.",
30: "FORCED: This means a configurable fault was escalated to a HardFault, either because the configurable fault handler was not enabled or a fault occurred within the handler.",
31: "DEBUGEVT: Indicates that a debug event (i.e executing a breakpoint instruction) occurred while the debug subsystem was not enabled.",
}
def print_errs(val, prefix, dict):
for bit, msg in dict.items():
if (val & (1 << bit)) != 0:
print(f"[{bit:2}] {prefix}: {msg}")
print_errs(UFSR, "UFSR", ufsr_faults)
print_errs(BFSR, "BFSR", bfsr_faults)
print_errs(MMFSR, "MMFSR", mmfsr_faults)
print_errs(HFSR, "HFSR", hfsr_faults)
end
end
define force_precise
set *((uint32_t*) 0xE000E008)=(*((uint32_t*)0xE000E008) | 1<<1)
end
define print_bfar
p/x *((uint32_t*)0xE000ED38)
end
define reflash
python
from os.path import basename, dirname, splitext, getmtime
import subprocess
# import pty
bin = gdb.objfiles()[0].filename
axf = splitext(bin)[0] + ".axf"
target = basename(dirname(bin))
before = getmtime(axf)
gdb.execute("shell ninja build-{} 2>&1".format(target), True)
after = getmtime(axf)
if before != after:
gdb.execute('monitor program "{}"'.format(axf))
end
end