Skip to content

Commit

Permalink
helpers.linux.idr: add idr_for_each_entry()
Browse files Browse the repository at this point in the history
This is a convenience wrapper around idr_for_each() and a cast.

Signed-off-by: Omar Sandoval <[email protected]>
  • Loading branch information
osandov committed Mar 5, 2024
1 parent 0562be0 commit 8aa9980
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
23 changes: 20 additions & 3 deletions drgn/helpers/linux/idr.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
"""

import operator
from typing import Iterator, Tuple
from typing import Iterator, Tuple, Union

from _drgn import _linux_helper_idr_find
from drgn import NULL, IntegerLike, Object, cast, sizeof
from drgn import NULL, IntegerLike, Object, Type, cast, sizeof
from drgn.helpers.linux.radixtree import radix_tree_for_each

__all__ = (
"idr_find",
"idr_for_each",
"idr_for_each_entry",
)

_IDR_BITS = 8
Expand Down Expand Up @@ -66,7 +67,7 @@ def idr_find(idr: Object, id: IntegerLike) -> Object:

def idr_for_each(idr: Object) -> Iterator[Tuple[int, Object]]:
"""
Iterate over all of the entries in an IDR.
Iterate over all of the pointers in an IDR.
:param idr: ``struct idr *``
:return: Iterator of (index, ``void *``) tuples.
Expand Down Expand Up @@ -97,3 +98,19 @@ def aux(p: Object, id: int, n: int) -> Iterator[Tuple[int, Object]]:
base = 0
for index, entry in radix_tree_for_each(idr_rt.address_of_()):
yield index + base, entry


def idr_for_each_entry(
idr: Object, type: Union[str, Type]
) -> Iterator[Tuple[int, Object]]:
"""
Iterate over all of the entries with the given type in an IDR.
:param idr: ``struct idr *``
:param type: Entry type.
:return: Iterator of (index, ``type *``) tuples.
"""
prog = idr.prog_
type = prog.pointer_type(prog.type(type))
for index, entry in idr_for_each(idr):
yield index, cast(type, entry)
13 changes: 12 additions & 1 deletion tests/linux_kernel/helpers/test_idr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: LGPL-2.1-or-later

from drgn import NULL, Object
from drgn.helpers.linux.idr import idr_find, idr_for_each
from drgn.helpers.linux.idr import idr_find, idr_for_each, idr_for_each_entry
from tests.linux_kernel import LinuxKernelTestCase, skip_unless_have_test_kmod


Expand Down Expand Up @@ -69,3 +69,14 @@ def test_idr_for_each_sparse(self):
(0xEE, Object(self.prog, "void *", 0x9ABC)),
],
)

def test_idr_for_each_entry(self):
root = self.prog["drgn_test_idr_sparse"].address_of_()
self.assertIdentical(
list(idr_for_each_entry(root, "int")),
[
(1, Object(self.prog, "int *", 0x1234)),
(0x80, Object(self.prog, "int *", 0x5678)),
(0xEE, Object(self.prog, "int *", 0x9ABC)),
],
)

0 comments on commit 8aa9980

Please sign in to comment.