]> git.wh0rd.org - home.git/blame - .gdbinit.py
cros-board: update
[home.git] / .gdbinit.py
CommitLineData
5b4483f1
MF
1#!/usr/bin/python3
2
3import inspect
4import os
5from pathlib import Path
6import sys
7
8import gdb
9
10
11#
12# Load frameworks if available.
13#
14
15if False:
16 PWNDBG = Path('/usr/local/src/pwndbg/gdbinit.py')
17 GDB_DASHBOARD = Path('/usr/local/src/gdb-dashboard/.gdbinit')
18 if PWNDBG.exists():
19 gdb.execute(f'source {PWNDBG}')
20 elif GDB_DASHBOARD.exists():
21 gdb.execute(f'source {GDB_DASHBOARD}')
22
23
24#
25# Random helpers.
26#
27
28TRACE = False
29
30class VapierCommand(gdb.Command):
31 """Base class for my custom commands."""
32
33 CMD_INIT = ()
34 CATCH_INVOKE_ERROR = True
35
36 def __init__(self):
37 gdb.Command.__init__(self, *self.CMD_INIT)
38
39 def invoke(self, arg, from_tty):
40 try:
41 if hasattr(self, 'v_invoke_argv'):
42 argv = gdb.string_to_argv(arg)
43 self.v_invoke_argv(argv, from_tty)
44 else:
45 self.v_invoke(arg, from_tty)
46 except gdb.error as e:
47 if self.CATCH_INVOKE_ERROR:
48 print(e, file=sys.stderr)
49 else:
50 raise
51
52 def v_exec(self, cmd):
53 if TRACE:
54 print(f'+ {cmd}')
55 gdb.execute(cmd)
56
57 def v_parse_int(self, arg):
58 try:
59 return int(arg)
60 except ValueError:
61 pass
62
63 try:
64 return int(arg, 16)
65 except ValueError as e:
66 raise gdb.error(f'Not a decimal or hex integer: {arg}')
67
68
69class VapierTraceCommand(VapierCommand):
70 """Toggle tracing of helpers."""
71
72 CMD_INIT = ('vapier-trace', gdb.COMMAND_SUPPORT)
73
74 def v_invoke(self, arg, from_tty):
75 global TRACE
76 if arg:
77 TRACE = bool(arg)
78 else:
79 TRACE = not TRACE
80 print(f'Tracing of vapier helpers is now {"on" if TRACE else "off"}')
81
82
83class ExitCommand(VapierCommand):
84 """Exit gdb.
85Alias to 'quit'.\
86"""
87 CMD_INIT = ('exit', gdb.COMMAND_SUPPORT)
88
89 def v_invoke(self, arg, from_tty):
90 self.dont_repeat()
91 self.v_exec(f'quit {arg}')
92
93
94class LoadBlackfinCommands(VapierCommand):
95 """Load Blackfin specific commands."""
96
97 BFIN_CONFIG = Path('~/.gdbinit.bfin').expanduser()
98 CMD_INIT = ('blackfin-commands', gdb.COMMAND_SUPPORT)
99
100 def v_invoke(self, arg, from_tty):
101 self.dont_repeat()
102 self.v_exec(f'source {self.BFIN_CONFIG}')
103
104
105class GoCommand(VapierCommand):
106 """A simple goto-like helper.
107Basically an alias to 'jump *<addr>'.\
108"""
109
110 CMD_INIT = ('go', gdb.COMMAND_RUNNING)
111
112 def v_invoke(self, arg, from_tty):
113 self.v_exec(f'jump *{arg}')
114
115
116class DiCommand(VapierCommand):
117
118 CMD_INIT = ('di', gdb.COMMAND_DATA)
119
120 def v_invoke_argv(self, argv, from_tty):
121 self.dont_repeat()
122 if not argv:
123 base = '$pc'
124 elif len(argv) == 1:
125 base = argv[0]
126 else:
127 raise gdb.error('di takes 0 or 1 arguments')
128 self.v_exec(f'disassemble {base} ({base} + 0x40)')
129
130
131class DisCommand(VapierCommand):
132
133 CMD_INIT = ('dis', gdb.COMMAND_DATA)
134
135 def v_invoke_argv(self, argv, from_tty):
136 self.dont_repeat()
137 if not argv:
138 base = '$pc'
139 elif len(argv) == 1:
140 base = argv[0]
141 else:
142 raise gdb.error('dis takes 0 or 1 arguments')
143 self.v_exec(f'disassemble {base},+0x40')
144
145
146class UBootMdCommand(VapierCommand):
147 """Display memory.
148Usage: md <unit type> <address> [count=64]
149Display [count] <unit type> starting at <address>.\
150"""
151
152 CMD_INIT = ('md', gdb.COMMAND_DATA)
153
154 def v_invoke_argv(self, argv, from_tty):
155 self.dont_repeat()
156 if len(argv) == 2:
157 count = 64
158 unit, addr = argv
159 elif len(argv) == 3:
160 unit, addr, count = argv
161 else:
162 raise gdb.error('usage: <unit> <addr> [count]')
163 self.v_exec(f'x/{count}x{unit} {addr}')
164
165
166class UBootMemoryDisplayCommand(VapierCommand):
167 """Display memory.
168Usage: md[cbwlq] <address> [count=64]
169Display [count] <chars|bytes|words|longs|quads> starting at <address>.\
170"""
171
172 UNIT = None
173 RADIX = 16
174
175 def v_invoke_argv(self, argv, from_tty):
176 assert self.UNIT
177 self.dont_repeat()
178
179 if len(argv) == 1:
180 count = 64
181 addr, = argv
182 elif len(argv) == 2:
183 addr, count = argv
184 else:
185 raise gdb.error('usage: <addr> [count]')
186
187 if self.RADIX != 16:
188 self.v_exec(f'set output-radix {self.RADIX}')
189 self.v_exec(f'md {self.UNIT} {addr} {count}')
190 if self.RADIX != 16:
191 self.v_exec(f'set output-radix 16')
192
193class UBootMdb(UBootMemoryDisplayCommand):
194 __doc__ = UBootMemoryDisplayCommand.__doc__
195 CMD_INIT = ('mdb', gdb.COMMAND_DATA)
196 UNIT = 'b'
197
198class UBootMdw(UBootMemoryDisplayCommand):
199 __doc__ = UBootMemoryDisplayCommand.__doc__
200 CMD_INIT = ('mdw', gdb.COMMAND_DATA)
201 UNIT = 'h'
202
203class UBootMdl(UBootMemoryDisplayCommand):
204 __doc__ = UBootMemoryDisplayCommand.__doc__
205 CMD_INIT = ('mdl', gdb.COMMAND_DATA)
206 UNIT = 'w'
207
208class UBootMdq(UBootMemoryDisplayCommand):
209 __doc__ = UBootMemoryDisplayCommand.__doc__
210 CMD_INIT = ('mdq', gdb.COMMAND_DATA)
211 UNIT = 'g'
212
213class UBootMdc(UBootMemoryDisplayCommand):
214 __doc__ = UBootMemoryDisplayCommand.__doc__
215 CMD_INIT = ('mdc', gdb.COMMAND_DATA)
216 UNIT = 'c'
217 RADIX = 10
218
219
220class UBootMemoryWriteCommand(VapierCommand):
221 """Write memory.
222Usage: mw[bwlq] <address> <value> <count>
223Set <count> <bytes|words|longs|quads> at <address> to <value>.\
224"""
225
226 UNIT = None
227
228 def v_invoke_argv(self, argv, from_tty):
229 assert self.UNIT
230 self.dont_repeat()
231
232 if len(argv) == 3:
233 addr, val, count = argv
234 else:
235 raise gdb.error('usage: <addr> <val> <count>')
236 count = self.v_parse_int(count)
237
238 offset = 0
239 while count > 0:
240 self.v_exec(f'set *(({self.UNIT}*){addr} + {offset}) = {val}')
241 offset += 1
242 count -= 1
243
244class UBootMwb(UBootMemoryWriteCommand):
245 __doc__ = UBootMemoryWriteCommand.__doc__
246 CMD_INIT = ('mwb', gdb.COMMAND_DATA)
247 UNIT = 'unsigned char'
248
249class UBootMww(UBootMemoryWriteCommand):
250 __doc__ = UBootMemoryWriteCommand.__doc__
251 CMD_INIT = ('mww', gdb.COMMAND_DATA)
252 UNIT = 'unsigned short'
253
254class UBootMwl(UBootMemoryWriteCommand):
255 __doc__ = UBootMemoryWriteCommand.__doc__
256 CMD_INIT = ('mwl', gdb.COMMAND_DATA)
257 UNIT = 'unsigned int'
258
259class UBootMwq(UBootMemoryWriteCommand):
260 __doc__ = UBootMemoryWriteCommand.__doc__
261 CMD_INIT = ('mwq', gdb.COMMAND_DATA)
262 UNIT = 'unsigned long long'
263
264
265#class UBootCompareCommand(VapierCommand):
266# """Compare memory regions.
267#Usage: cmp[bwlq] <address> <address> <count>
268#Compare <count> <bytes|words|longs|quads> between <address> and <address>.\
269#"""
270#
271# UNIT = None
272#
273# def v_invoke_argv(self, argv, from_tty):
274# assert self.UNIT
275# self.dont_repeat()
276#
277# if len(argv) == 3:
278# addr1, addr2, count = argv
279# else:
280# raise gdb.error('usage: <addr1> <addr2> <count>')
281# count = self.v_parse_int(count)
282#
283# set $$addr1 = $arg0
284# set $$addr2 = $arg1
285# set $$count = $arg2
286# while $$count-- > 0
287# if (*$$addr1 != *$$addr2)
288# printf "Data mismatch at %#x units (@%#x != @%#x)\n", $arg2, $$addr1, $$addr2
289# set $$count = -100
290# end
291# set $$addr1 += 1
292# set $$addr2 += 1
293# end
294# if $$count == -1
295# printf "Data matches for %#x units\n", $arg2
296# end
297#
298#class UBootCmpb(UBootCompareCommand):
299# __doc__ = UBootCompareCommand.__doc__
300# CMD_INIT = ('cmpb', gdb.COMMAND_DATA)
301# UNIT = 'unsigned char'
302#
303#class UBootCmpw(UBootCompareCommand):
304# __doc__ = UBootCompareCommand.__doc__
305# CMD_INIT = ('cmpw', gdb.COMMAND_DATA)
306# UNIT = 'unsigned short'
307#
308#class UBootCmpl(UBootCompareCommand):
309# __doc__ = UBootCompareCommand.__doc__
310# CMD_INIT = ('cmpl', gdb.COMMAND_DATA)
311# UNIT = 'unsigned int'
312#
313#class UBootCmpq(UBootCompareCommand):
314# __doc__ = UBootCompareCommand.__doc__
315# CMD_INIT = ('cmpq', gdb.COMMAND_DATA)
316# UNIT = 'unsigned long long'
317#
318#
319#class UBootCopyCommand(VapierCommand):
320# """Copy memory regions.
321#Usage: cp[bwlq] <src> <dst> <count>
322#Copy <count> <bytes|words|longs|quads> from <src> to <dst>.\
323#"""
324#
325# UNIT = None
326#
327# def v_invoke_argv(self, argv, from_tty):
328# assert self.UNIT
329# self.dont_repeat()
330#
331# if len(argv) == 3:
332# src, dst, count = argv
333# else:
334# raise gdb.error('usage: <addr1> <addr2> <count>')
335# count = self.v_parse_int(count)
336#
337# offset = 0
338# while count > 0:
339# self.v_exec(f'set *(({self.UNIT}*){addr} + {offset}) = {val}')
340# count -= 1
341# offset += 1
342# set *$$dst = *$$src
343# set $$src += 1
344# set $$dst += 1
345# print(f'Copied {argv[2]} units from {addr1} to {addr2}')
346#
347#class UBootCpb(UBootCopyCommand):
348# __doc__ = UBootCopyCommand.__doc__
349# CMD_INIT = ('cpb', gdb.COMMAND_DATA)
350# UNIT = 'unsigned char'
351#
352#class UBootCpw(UBootCopyCommand):
353# __doc__ = UBootCopyCommand.__doc__
354# CMD_INIT = ('cpw', gdb.COMMAND_DATA)
355# UNIT = 'unsigned short'
356#
357#class UBootCpl(UBootCopyCommand):
358# __doc__ = UBootCopyCommand.__doc__
359# CMD_INIT = ('cpl', gdb.COMMAND_DATA)
360# UNIT = 'unsigned int'
361#
362#class UBootCpq(UBootCopyCommand):
363# __doc__ = UBootCopyCommand.__doc__
364# CMD_INIT = ('cpq', gdb.COMMAND_DATA)
365# UNIT = 'unsigned long long'
366
367
368# Probe & load all commands registered.
369for cls in list(globals().values()):
370 if (inspect.isclass(cls) and
371 issubclass(cls, VapierCommand) and
372 cls.CMD_INIT):
373 cls()