aboutsummaryrefslogtreecommitdiff
path: root/scripts/gdb/linux/radixtree.py
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-06-07 13:04:56 -0300
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-06-07 13:04:56 -0300
commitc853f18b640f3e58ba14ffb25e551be8af218209 (patch)
tree89adc65667f124c21f2104422fcaed991da450ab /scripts/gdb/linux/radixtree.py
parentaff093d4bbca91f543e24cde2135f393b8130f4b (diff)
parentaf8c34ce6ae32addda3788d54a7e340cad22516b (diff)
Merge tag 'v4.7-rc2' into v4l_for_linus
Linux 4.7-rc2 * tag 'v4.7-rc2': (10914 commits) Linux 4.7-rc2 devpts: Make each mount of devpts an independent filesystem. parisc: Move die_if_kernel() prototype into traps.h header parisc: Fix pagefault crash in unaligned __get_user() call parisc: Fix printk time during boot parisc: Fix backtrace on PA-RISC mm, page_alloc: recalculate the preferred zoneref if the context can ignore memory policies mm, page_alloc: reset zonelist iterator after resetting fair zone allocation policy mm, oom_reaper: do not use siglock in try_oom_reaper() mm, page_alloc: prevent infinite loop in buffered_rmqueue() checkpatch: reduce git commit description style false positives mm/z3fold.c: avoid modifying HEADLESS page and minor cleanup memcg: add RCU locking around css_for_each_descendant_pre() in memcg_offline_kmem() mm: check the return value of lookup_page_ext for all call sites kdump: fix dmesg gdbmacro to work with record based printk mm: fix overflow in vm_map_ram() Btrfs: deal with duplciates during extent_map insertion in btrfs_get_extent arm64: fix alignment when RANDOMIZE_TEXT_OFFSET is enabled arm64: move {PAGE,CONT}_SHIFT into Kconfig arm64: mm: dump: log span level ...
Diffstat (limited to 'scripts/gdb/linux/radixtree.py')
-rw-r--r--scripts/gdb/linux/radixtree.py97
1 files changed, 97 insertions, 0 deletions
diff --git a/scripts/gdb/linux/radixtree.py b/scripts/gdb/linux/radixtree.py
new file mode 100644
index 000000000000..0fdef4e2971a
--- /dev/null
+++ b/scripts/gdb/linux/radixtree.py
@@ -0,0 +1,97 @@
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+# Radix Tree Parser
+#
+# Copyright (c) 2016 Linaro Ltd
+#
+# Authors:
+# Kieran Bingham <kieran.bingham@linaro.org>
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+import gdb
+
+from linux import utils
+from linux import constants
+
+radix_tree_root_type = utils.CachedType("struct radix_tree_root")
+radix_tree_node_type = utils.CachedType("struct radix_tree_node")
+
+
+def is_indirect_ptr(node):
+ long_type = utils.get_long_type()
+ return (node.cast(long_type) & constants.LX_RADIX_TREE_INDIRECT_PTR)
+
+
+def indirect_to_ptr(node):
+ long_type = utils.get_long_type()
+ node_type = node.type
+ indirect_ptr = node.cast(long_type) & ~constants.LX_RADIX_TREE_INDIRECT_PTR
+ return indirect_ptr.cast(node_type)
+
+
+def maxindex(height):
+ height = height & constants.LX_RADIX_TREE_HEIGHT_MASK
+ return gdb.parse_and_eval("height_to_maxindex["+str(height)+"]")
+
+
+def lookup(root, index):
+ if root.type == radix_tree_root_type.get_type().pointer():
+ root = root.dereference()
+ elif root.type != radix_tree_root_type.get_type():
+ raise gdb.GdbError("Must be struct radix_tree_root not {}"
+ .format(root.type))
+
+ node = root['rnode']
+ if node is 0:
+ return None
+
+ if not (is_indirect_ptr(node)):
+ if (index > 0):
+ return None
+ return node
+
+ node = indirect_to_ptr(node)
+
+ height = node['path'] & constants.LX_RADIX_TREE_HEIGHT_MASK
+ if (index > maxindex(height)):
+ return None
+
+ shift = (height-1) * constants.LX_RADIX_TREE_MAP_SHIFT
+
+ while True:
+ new_index = (index >> shift) & constants.LX_RADIX_TREE_MAP_MASK
+ slot = node['slots'][new_index]
+
+ node = slot.cast(node.type.pointer()).dereference()
+ if node is 0:
+ return None
+
+ shift -= constants.LX_RADIX_TREE_MAP_SHIFT
+ height -= 1
+
+ if (height <= 0):
+ break
+
+ return node
+
+
+class LxRadixTree(gdb.Function):
+ """ Lookup and return a node from a RadixTree.
+
+$lx_radix_tree_lookup(root_node [, index]): Return the node at the given index.
+If index is omitted, the root node is dereferenced and returned."""
+
+ def __init__(self):
+ super(LxRadixTree, self).__init__("lx_radix_tree_lookup")
+
+ def invoke(self, root, index=0):
+ result = lookup(root, index)
+ if result is None:
+ raise gdb.GdbError("No entry in tree at index {}".format(index))
+
+ return result
+
+LxRadixTree()