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