blob: 2a46eaadad6f9a1b121b706e77d45882e4690959 [file] [log] [blame]
import gdb
import re
from gdb_providers import *
from rust_types import *
rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string=True)
_gdb_version_matched = re.search('([0-9]+)\\.([0-9]+)', gdb.VERSION)
gdb_version = [int(num) for num in _gdb_version_matched.groups()] if _gdb_version_matched else []
def register_printers(objfile):
objfile.pretty_printers.append(lookup)
# BACKCOMPAT: rust 1.35
def is_hashbrown_hashmap(hash_map):
return len(hash_map.type.fields()) == 1
def classify_rust_type(type):
type_class = type.code
if type_class == gdb.TYPE_CODE_STRUCT:
return classify_struct(type.tag, type.fields())
if type_class == gdb.TYPE_CODE_UNION:
return classify_union(type.fields())
return RustType.OTHER
def check_enum_discriminant(valobj):
content = valobj[valobj.type.fields()[0]]
fields = content.type.fields()
if len(fields) > 1:
discriminant = int(content[fields[0]]) + 1
if discriminant > len(fields):
# invalid discriminant
return False
return True
def lookup(valobj):
rust_type = classify_rust_type(valobj.type)
if rust_type == RustType.ENUM:
# use enum provider only for GDB <7.12
if gdb_version[0] < 7 or (gdb_version[0] == 7 and gdb_version[1] < 12):
if check_enum_discriminant(valobj):
return EnumProvider(valobj)
if rust_type == RustType.STD_STRING:
return StdStringProvider(valobj)
if rust_type == RustType.STD_OS_STRING:
return StdOsStringProvider(valobj)
if rust_type == RustType.STD_STR and not rust_enabled:
return StdStrProvider(valobj)
if rust_type == RustType.STD_VEC:
return StdVecProvider(valobj)
if rust_type == RustType.STD_VEC_DEQUE:
return StdVecDequeProvider(valobj)
if rust_type == RustType.STD_BTREE_SET:
return StdBTreeSetProvider(valobj)
if rust_type == RustType.STD_BTREE_MAP:
return StdBTreeMapProvider(valobj)
if rust_type == RustType.STD_HASH_MAP:
if is_hashbrown_hashmap(valobj):
return StdHashMapProvider(valobj)
else:
return StdOldHashMapProvider(valobj)
if rust_type == RustType.STD_HASH_SET:
hash_map = valobj["map"]
if is_hashbrown_hashmap(hash_map):
return StdHashMapProvider(hash_map, show_values=False)
else:
return StdOldHashMapProvider(hash_map, show_values=False)
if rust_type == RustType.STD_RC:
return StdRcProvider(valobj)
if rust_type == RustType.STD_ARC:
return StdRcProvider(valobj, is_atomic=True)
if rust_type == RustType.STD_CELL:
return StdCellProvider(valobj)
if rust_type == RustType.STD_REF:
return StdRefProvider(valobj)
if rust_type == RustType.STD_REF_MUT:
return StdRefProvider(valobj)
if rust_type == RustType.STD_REF_CELL:
return StdRefCellProvider(valobj)
return None