Loading...
Note: File does not exist in v5.9.
1# SPDX-License-Identifier: GPL-2.0
2#
3# Radix Tree Parser
4#
5# Copyright (c) 2016 Linaro Ltd
6# Copyright (c) 2023 Broadcom
7#
8# Authors:
9# Kieran Bingham <kieran.bingham@linaro.org>
10# Florian Fainelli <f.fainelli@gmail.com>
11
12import gdb
13
14from linux import utils
15from linux import constants
16
17radix_tree_root_type = utils.CachedType("struct xarray")
18radix_tree_node_type = utils.CachedType("struct xa_node")
19
20def is_internal_node(node):
21 long_type = utils.get_long_type()
22 return ((node.cast(long_type) & constants.LX_RADIX_TREE_ENTRY_MASK) == constants.LX_RADIX_TREE_INTERNAL_NODE)
23
24def entry_to_node(node):
25 long_type = utils.get_long_type()
26 node_type = node.type
27 indirect_ptr = node.cast(long_type) & ~constants.LX_RADIX_TREE_INTERNAL_NODE
28 return indirect_ptr.cast(radix_tree_node_type.get_type().pointer())
29
30def node_maxindex(node):
31 return (constants.LX_RADIX_TREE_MAP_SIZE << node['shift']) - 1
32
33def lookup(root, index):
34 if root.type == radix_tree_root_type.get_type().pointer():
35 node = root.dereference()
36 elif root.type != radix_tree_root_type.get_type():
37 raise gdb.GdbError("must be {} not {}"
38 .format(radix_tree_root_type.get_type(), root.type))
39
40 node = root['xa_head']
41 if node == 0:
42 return None
43
44 if not (is_internal_node(node)):
45 if (index > 0):
46 return None
47 return node
48
49 node = entry_to_node(node)
50 maxindex = node_maxindex(node)
51
52 if (index > maxindex):
53 return None
54
55 shift = node['shift'] + constants.LX_RADIX_TREE_MAP_SHIFT
56
57 while True:
58 offset = (index >> node['shift']) & constants.LX_RADIX_TREE_MAP_MASK
59 slot = node['slots'][offset]
60
61 if slot == 0:
62 return None
63
64 node = slot.cast(node.type.pointer()).dereference()
65 if node == 0:
66 return None
67
68 shift -= constants.LX_RADIX_TREE_MAP_SHIFT
69 if (shift <= 0):
70 break
71
72 return node
73
74class LxRadixTree(gdb.Function):
75 """ Lookup and return a node from a RadixTree.
76
77$lx_radix_tree_lookup(root_node [, index]): Return the node at the given index.
78If index is omitted, the root node is dereference and returned."""
79
80 def __init__(self):
81 super(LxRadixTree, self).__init__("lx_radix_tree_lookup")
82
83 def invoke(self, root, index=0):
84 result = lookup(root, index)
85 if result is None:
86 raise gdb.GdbError("No entry in tree at index {}".format(index))
87
88 return result
89
90LxRadixTree()