• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import gdb
2import re
3
4from gdb_providers import *
5from rust_types import *
6
7
8_gdb_version_matched = re.search('([0-9]+)\\.([0-9]+)', gdb.VERSION)
9gdb_version = [int(num) for num in _gdb_version_matched.groups()] if _gdb_version_matched else []
10
11def register_printers(objfile):
12    objfile.pretty_printers.append(lookup)
13
14
15# BACKCOMPAT: rust 1.35
16def is_hashbrown_hashmap(hash_map):
17    return len(hash_map.type.fields()) == 1
18
19
20def classify_rust_type(type):
21    type_class = type.code
22    if type_class == gdb.TYPE_CODE_STRUCT:
23        return classify_struct(type.tag, type.fields())
24    if type_class == gdb.TYPE_CODE_UNION:
25        return classify_union(type.fields())
26
27    return RustType.OTHER
28
29
30def check_enum_discriminant(valobj):
31    content = valobj[valobj.type.fields()[0]]
32    fields = content.type.fields()
33    if len(fields) > 1:
34        discriminant = int(content[fields[0]]) + 1
35        if discriminant > len(fields):
36            # invalid discriminant
37            return False
38    return True
39
40
41def lookup(valobj):
42    rust_type = classify_rust_type(valobj.type)
43
44    if rust_type == RustType.ENUM:
45        # use enum provider only for GDB <7.12
46        if gdb_version[0] < 7 or (gdb_version[0] == 7 and gdb_version[1] < 12):
47            if check_enum_discriminant(valobj):
48                return EnumProvider(valobj)
49
50    if rust_type == RustType.STD_STRING:
51        return StdStringProvider(valobj)
52    if rust_type == RustType.STD_OS_STRING:
53        return StdOsStringProvider(valobj)
54    if rust_type == RustType.STD_STR:
55        return StdStrProvider(valobj)
56    if rust_type == RustType.STD_SLICE:
57        return StdSliceProvider(valobj)
58    if rust_type == RustType.STD_VEC:
59        return StdVecProvider(valobj)
60    if rust_type == RustType.STD_VEC_DEQUE:
61        return StdVecDequeProvider(valobj)
62    if rust_type == RustType.STD_BTREE_SET:
63        return StdBTreeSetProvider(valobj)
64    if rust_type == RustType.STD_BTREE_MAP:
65        return StdBTreeMapProvider(valobj)
66    if rust_type == RustType.STD_HASH_MAP:
67        if is_hashbrown_hashmap(valobj):
68            return StdHashMapProvider(valobj)
69        else:
70            return StdOldHashMapProvider(valobj)
71    if rust_type == RustType.STD_HASH_SET:
72        hash_map = valobj[valobj.type.fields()[0]]
73        if is_hashbrown_hashmap(hash_map):
74            return StdHashMapProvider(valobj, show_values=False)
75        else:
76            return StdOldHashMapProvider(hash_map, show_values=False)
77
78    if rust_type == RustType.STD_RC:
79        return StdRcProvider(valobj)
80    if rust_type == RustType.STD_ARC:
81        return StdRcProvider(valobj, is_atomic=True)
82
83    if rust_type == RustType.STD_CELL:
84        return StdCellProvider(valobj)
85    if rust_type == RustType.STD_REF:
86        return StdRefProvider(valobj)
87    if rust_type == RustType.STD_REF_MUT:
88        return StdRefProvider(valobj)
89    if rust_type == RustType.STD_REF_CELL:
90        return StdRefCellProvider(valobj)
91
92    if rust_type == RustType.STD_NONZERO_NUMBER:
93        return StdNonZeroNumberProvider(valobj)
94
95    return None
96