summaryrefslogtreecommitdiffstats
path: root/src/etc/gdb_lookup.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/etc/gdb_lookup.py')
-rw-r--r--src/etc/gdb_lookup.py92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/etc/gdb_lookup.py b/src/etc/gdb_lookup.py
new file mode 100644
index 000000000..292e91b4d
--- /dev/null
+++ b/src/etc/gdb_lookup.py
@@ -0,0 +1,92 @@
+import gdb
+import re
+
+from gdb_providers import *
+from rust_types import *
+
+
+_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:
+ return StdStrProvider(valobj)
+ if rust_type == RustType.STD_SLICE:
+ return StdSliceProvider(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[valobj.type.fields()[0]]
+ if is_hashbrown_hashmap(hash_map):
+ return StdHashMapProvider(valobj, 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