summaryrefslogtreecommitdiff
path: root/gdb_plugins/mmio.py
blob: 25ebcc3943bd4d4561e5da9825d958a5ca918272 (plain)
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
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)