summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorStephen Boyd <swboyd@chromium.org>2019-05-14 18:45:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-14 22:52:51 -0400
commit449ca0c95ea261f27b7efd4ca3970a5b4e0fd30d (patch)
treecccf8232f9b50cd85409a8cd69fcd9aceeb143f3 /scripts
parent90cf83dbd2f08dd0513cd9f19155878c55acb445 (diff)
scripts/gdb: add rb tree iterating utilities
Implement gdb functions for rb_first(), rb_last(), rb_next(), and rb_prev(). These can be useful to iterate through the kernel's red-black trees. [swboyd@chromium.org: v2] Link: http://lkml.kernel.org/r/20190329220844.38234-4-swboyd@chromium.org Link: http://lkml.kernel.org/r/20190325184522.260535-4-swboyd@chromium.org Signed-off-by: Stephen Boyd <swboyd@chromium.org> Cc: Douglas Anderson <dianders@chromium.org> Cc: Nikolay Borisov <n.borisov.lkml@gmail.com> Cc: Kieran Bingham <kbingham@kernel.org> Cc: Jan Kiszka <jan.kiszka@siemens.com> Cc: Jackie Liu <liuyun01@kylinos.cn> Cc: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/gdb/linux/rbtree.py177
-rw-r--r--scripts/gdb/vmlinux-gdb.py1
2 files changed, 178 insertions, 0 deletions
diff --git a/scripts/gdb/linux/rbtree.py b/scripts/gdb/linux/rbtree.py
new file mode 100644
index 000000000000..39db889b874c
--- /dev/null
+++ b/scripts/gdb/linux/rbtree.py
@@ -0,0 +1,177 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# Copyright 2019 Google LLC.
4
5import gdb
6
7from linux import utils
8
9rb_root_type = utils.CachedType("struct rb_root")
10rb_node_type = utils.CachedType("struct rb_node")
11
12
13def rb_first(root):
14 if root.type == rb_root_type.get_type():
15 node = node.address.cast(rb_root_type.get_type().pointer())
16 elif root.type != rb_root_type.get_type().pointer():
17 raise gdb.GdbError("Must be struct rb_root not {}".format(root.type))
18
19 node = root['rb_node']
20 if node is 0:
21 return None
22
23 while node['rb_left']:
24 node = node['rb_left']
25
26 return node
27
28
29def rb_last(root):
30 if root.type == rb_root_type.get_type():
31 node = node.address.cast(rb_root_type.get_type().pointer())
32 elif root.type != rb_root_type.get_type().pointer():
33 raise gdb.GdbError("Must be struct rb_root not {}".format(root.type))
34
35 node = root['rb_node']
36 if node is 0:
37 return None
38
39 while node['rb_right']:
40 node = node['rb_right']
41
42 return node
43
44
45def rb_parent(node):
46 parent = gdb.Value(node['__rb_parent_color'] & ~3)
47 return parent.cast(rb_node_type.get_type().pointer())
48
49
50def rb_empty_node(node):
51 return node['__rb_parent_color'] == node.address
52
53
54def rb_next(node):
55 if node.type == rb_node_type.get_type():
56 node = node.address.cast(rb_node_type.get_type().pointer())
57 elif node.type != rb_node_type.get_type().pointer():
58 raise gdb.GdbError("Must be struct rb_node not {}".format(node.type))
59
60 if rb_empty_node(node):
61 return None
62
63 if node['rb_right']:
64 node = node['rb_right']
65 while node['rb_left']:
66 node = node['rb_left']
67 return node
68
69 parent = rb_parent(node)
70 while parent and node == parent['rb_right']:
71 node = parent
72 parent = rb_parent(node)
73
74 return parent
75
76
77def rb_prev(node):
78 if node.type == rb_node_type.get_type():
79 node = node.address.cast(rb_node_type.get_type().pointer())
80 elif node.type != rb_node_type.get_type().pointer():
81 raise gdb.GdbError("Must be struct rb_node not {}".format(node.type))
82
83 if rb_empty_node(node):
84 return None
85
86 if node['rb_left']:
87 node = node['rb_left']
88 while node['rb_right']:
89 node = node['rb_right']
90 return node.dereference()
91
92 parent = rb_parent(node)
93 while parent and node == parent['rb_left'].dereference():
94 node = parent
95 parent = rb_parent(node)
96
97 return parent
98
99
100class LxRbFirst(gdb.Function):
101 """Lookup and return a node from an RBTree
102
103$lx_rb_first(root): Return the node at the given index.
104If index is omitted, the root node is dereferenced and returned."""
105
106 def __init__(self):
107 super(LxRbFirst, self).__init__("lx_rb_first")
108
109 def invoke(self, root):
110 result = rb_first(root)
111 if result is None:
112 raise gdb.GdbError("No entry in tree")
113
114 return result
115
116
117LxRbFirst()
118
119
120class LxRbLast(gdb.Function):
121 """Lookup and return a node from an RBTree.
122
123$lx_rb_last(root): Return the node at the given index.
124If index is omitted, the root node is dereferenced and returned."""
125
126 def __init__(self):
127 super(LxRbLast, self).__init__("lx_rb_last")
128
129 def invoke(self, root):
130 result = rb_last(root)
131 if result is None:
132 raise gdb.GdbError("No entry in tree")
133
134 return result
135
136
137LxRbLast()
138
139
140class LxRbNext(gdb.Function):
141 """Lookup and return a node from an RBTree.
142
143$lx_rb_next(node): Return the node at the given index.
144If index is omitted, the root node is dereferenced and returned."""
145
146 def __init__(self):
147 super(LxRbNext, self).__init__("lx_rb_next")
148
149 def invoke(self, node):
150 result = rb_next(node)
151 if result is None:
152 raise gdb.GdbError("No entry in tree")
153
154 return result
155
156
157LxRbNext()
158
159
160class LxRbPrev(gdb.Function):
161 """Lookup and return a node from an RBTree.
162
163$lx_rb_prev(node): Return the node at the given index.
164If index is omitted, the root node is dereferenced and returned."""
165
166 def __init__(self):
167 super(LxRbPrev, self).__init__("lx_rb_prev")
168
169 def invoke(self, node):
170 result = rb_prev(node)
171 if result is None:
172 raise gdb.GdbError("No entry in tree")
173
174 return result
175
176
177LxRbPrev()
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
index be0efb5dda5b..89e4aa4f8966 100644
--- a/scripts/gdb/vmlinux-gdb.py
+++ b/scripts/gdb/vmlinux-gdb.py
@@ -30,5 +30,6 @@ else:
30 import linux.config 30 import linux.config
31 import linux.cpus 31 import linux.cpus
32 import linux.lists 32 import linux.lists
33 import linux.rbtree
33 import linux.proc 34 import linux.proc
34 import linux.constants 35 import linux.constants