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
|
import gdb
import gdb.xmethod
class RefWorker(gdb.xmethod.XMethodWorker):
def __init__(self, result_type):
self.result_type = result_type
def get_arg_types(self):
return None
def get_result_type(self, obj):
return self.result_type.reference()
def __call__(self, obj):
return obj['p'].cast(self.result_type.pointer()).dereference()
class PtrWorker(gdb.xmethod.XMethodWorker):
def __init__(self, result_type):
self.result_type = result_type
def get_arg_types(self):
return None
def get_result_type(self, obj):
return self.result_type.pointer()
def __call__(self, obj):
return obj['p'].cast(self.result_type.pointer())
class SubscriptWorker(gdb.xmethod.XMethodWorker):
def __init__(self, result_type):
self.result_type = result_type
def get_arg_types(self):
return [gdb.lookup_type('std::size_t')]
def get_result_type(self, obj, idx):
return self.result_type.reference()
def __call__(self, obj, idx):
return obj['p'].cast(self.result_type.pointer())[idx]
class Method(gdb.xmethod.XMethod):
def __init__(self, name, worker):
gdb.xmethod.XMethod.__init__(self, name)
self.worker = worker
class Matcher(gdb.xmethod.XMethodMatcher):
def __init__(self):
gdb.xmethod.XMethodMatcher.__init__(self, 'mmio_ptr matcher')
self.methods = [
Method('operator*', RefWorker),
Method('operator->', PtrWorker),
Method('operator[]', SubscriptWorker),
]
def match(self, class_type, method_name):
if not class_type.name.startswith('mmio_ptr<'):
return
ptr_type = class_type.template_argument(0)
for method in self.methods:
if method.enabled and method.name == method_name:
return method.worker(ptr_type)
gdb.xmethod.register_xmethod_matcher(None, Matcher(), replace = True)
def get_mmio_ptr_type(pt):
if pt.name.startswith('mmio_ptr<'):
return pt.template_argument(0)
for field in pt.fields():
if not field.is_base_class:
continue
t = get_mmio_ptr_type(field.type)
if t is not None:
return t
return None
class MMIOPtr(gdb.Function):
"""
Usage is, for instance, p /x *$mmio_ptr(RCC)
"""
def __init__(self):
gdb.Function.__init__(self, 'mmio_ptr')
def invoke(self, obj):
t = get_mmio_ptr_type(obj.type)
return obj['p'].cast(t.pointer())
MMIOPtr()
|