mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-23 17:53:07 +00:00
Make cast() a function instead of a method
This commit is contained in:
parent
3b998be960
commit
9a4262b609
@ -47,6 +47,16 @@ from drgn.type import Type, PointerType
|
||||
from drgn.typename import TypeName
|
||||
|
||||
|
||||
def cast(type: Union[str, Type, TypeName], obj: Object) -> Object:
|
||||
"""
|
||||
Return a copy of the given object casted to another type. The given
|
||||
type is usually a string, but it can also be a Type or TypeName object.
|
||||
"""
|
||||
if not isinstance(type, Type):
|
||||
type = obj.prog_.type(type)
|
||||
return Object(obj.prog_, type, value=obj._value, address=obj.address_)
|
||||
|
||||
|
||||
def container_of(ptr: Object, type: Union[str, Type, TypeName],
|
||||
member: str) -> Object:
|
||||
"""
|
||||
|
@ -8,7 +8,7 @@ This module provides helpers for working with Linux devices, including the
|
||||
kernel encoding of dev_t.
|
||||
"""
|
||||
|
||||
from drgn import Object
|
||||
from drgn import cast, Object
|
||||
|
||||
__all__ = [
|
||||
'MAJOR',
|
||||
@ -30,7 +30,7 @@ def MAJOR(dev):
|
||||
"""
|
||||
major = dev >> _MINORBITS
|
||||
if isinstance(major, Object):
|
||||
return major.cast_('unsigned int')
|
||||
return cast('unsigned int', major)
|
||||
return major
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ def MINOR(dev):
|
||||
"""
|
||||
minor = dev & _MINORMASK
|
||||
if isinstance(minor, Object):
|
||||
return minor.cast_('unsigned int')
|
||||
return cast('unsigned int', minor)
|
||||
return minor
|
||||
|
||||
|
||||
@ -54,5 +54,5 @@ def MKDEV(major, minor):
|
||||
"""
|
||||
dev = (major << _MINORBITS) | minor
|
||||
if isinstance(dev, Object):
|
||||
return dev.cast_('dev_t')
|
||||
return cast('dev_t', dev)
|
||||
return dev
|
||||
|
@ -8,7 +8,7 @@ This module provides helpers for working with the Linux memory management (mm)
|
||||
subsystem. Only x86-64 support is currently implemented.
|
||||
"""
|
||||
|
||||
from drgn import Object
|
||||
from drgn import cast, Object
|
||||
|
||||
|
||||
__all__ = [
|
||||
@ -25,7 +25,7 @@ __all__ = [
|
||||
def _vmemmap(prog):
|
||||
try:
|
||||
# KASAN
|
||||
return prog['vmemmap_base'].cast_('struct page *')
|
||||
return cast('struct page *', prog['vmemmap_base'])
|
||||
except KeyError:
|
||||
# x86-64
|
||||
return Object(prog, 'struct page *', value=0xffffea0000000000)
|
||||
@ -57,7 +57,7 @@ def page_to_pfn(page):
|
||||
|
||||
Get the page frame number (PFN) of a page.
|
||||
"""
|
||||
return (page - _vmemmap(page.prog_)).cast_('unsigned long')
|
||||
return cast('unsigned long', page - _vmemmap(page.prog_))
|
||||
|
||||
|
||||
def pfn_to_page(prog_or_pfn, pfn=None):
|
||||
|
@ -7,7 +7,7 @@ Linux kernel process ID helpers
|
||||
This module provides helpers for looking up process IDs.
|
||||
"""
|
||||
|
||||
from drgn import container_of, NULL, Program
|
||||
from drgn import cast, container_of, NULL, Program
|
||||
from drgn.helpers.kernel.idr import idr_find, idr_for_each
|
||||
from drgn.helpers.kernel.list import hlist_for_each_entry
|
||||
|
||||
@ -34,7 +34,7 @@ def find_pid(prog_or_ns, nr):
|
||||
prog = prog_or_ns.prog_
|
||||
ns = prog_or_ns
|
||||
if hasattr(ns, 'idr'):
|
||||
return idr_find(ns.idr, nr).cast_('struct pid *')
|
||||
return cast('struct pid *', idr_find(ns.idr, nr))
|
||||
else:
|
||||
# We could implement pid_hashfn() and only search that bucket, but it's
|
||||
# different for 32-bit and 64-bit systems, and it has changed at least
|
||||
@ -67,7 +67,7 @@ def for_each_pid(prog_or_ns):
|
||||
ns = prog_or_ns
|
||||
if hasattr(ns, 'idr'):
|
||||
for nr, entry in idr_for_each(ns.idr):
|
||||
yield entry.cast_('struct pid *')
|
||||
yield cast('struct pid *', entry)
|
||||
else:
|
||||
pid_hash = prog['pid_hash']
|
||||
for i in range(1 << prog['pidhash_shift'].value_()):
|
||||
|
@ -8,7 +8,7 @@ This module provides helpers for working with radix trees from
|
||||
"linux/radix-tree.h".
|
||||
"""
|
||||
|
||||
from drgn import Object
|
||||
from drgn import cast, Object
|
||||
|
||||
|
||||
__all__ = [
|
||||
@ -33,7 +33,7 @@ def _radix_tree_root_node(root):
|
||||
except AttributeError:
|
||||
return root.rnode.read_once_(), 1
|
||||
else:
|
||||
return node.cast_('struct xa_node *').read_once_(), 2
|
||||
return cast('struct xa_node *', node).read_once_(), 2
|
||||
|
||||
|
||||
def radix_tree_lookup(root, index):
|
||||
@ -50,8 +50,8 @@ def radix_tree_lookup(root, index):
|
||||
break
|
||||
parent = _entry_to_node(node, RADIX_TREE_INTERNAL_NODE)
|
||||
offset = (index >> parent.shift) & RADIX_TREE_MAP_MASK
|
||||
node = parent.slots[offset].cast_(parent.type_).read_once_()
|
||||
return node.cast_('void *')
|
||||
node = cast(parent.type_, parent.slots[offset]).read_once_()
|
||||
return cast('void *', node)
|
||||
|
||||
|
||||
def radix_tree_for_each(root):
|
||||
@ -66,8 +66,8 @@ def radix_tree_for_each(root):
|
||||
if _is_internal_node(node, RADIX_TREE_INTERNAL_NODE):
|
||||
parent = _entry_to_node(node, RADIX_TREE_INTERNAL_NODE)
|
||||
for i, slot in enumerate(parent.slots):
|
||||
yield from aux(slot.cast_(parent.type_).read_once_(),
|
||||
yield from aux(cast(parent.type_, slot).read_once_(),
|
||||
index + (i << parent.shift.value_()))
|
||||
elif node:
|
||||
yield index, node.cast_('void *')
|
||||
yield index, cast('void *', node)
|
||||
yield from aux(node, 0)
|
||||
|
@ -80,7 +80,8 @@ def main() -> None:
|
||||
from drgn.internal.rlcompleter import Completer
|
||||
|
||||
init_globals['drgn'] = drgn
|
||||
for attr in ['container_of', 'Object', 'NULL']:
|
||||
drgn_globals = ['cast', 'container_of', 'NULL', 'Object']
|
||||
for attr in drgn_globals:
|
||||
init_globals[attr] = getattr(drgn, attr)
|
||||
init_globals['__name__'] = '__main__'
|
||||
init_globals['__doc__'] = None
|
||||
@ -102,7 +103,7 @@ def main() -> None:
|
||||
banner = version + """
|
||||
For help, type help(drgn).
|
||||
>>> import drgn
|
||||
>>> from drgn import container_of, Object, NULL"""
|
||||
>>> from drgn import """ + ', '.join(drgn_globals)
|
||||
if prog._is_kernel():
|
||||
banner += '\n>>> from drgn.helpers.kernel import *'
|
||||
module = importlib.import_module('drgn.helpers.kernel')
|
||||
|
@ -246,16 +246,6 @@ class Object:
|
||||
raise ValueError(f'member access must be on a struct or union, not {self.type_.name!r}') from None
|
||||
return Object(self.prog_, member_type, address=address + offset)
|
||||
|
||||
def cast_(self, type: Union[str, Type, TypeName]) -> 'Object':
|
||||
"""
|
||||
Return a copy of this object casted to another type. The given type is
|
||||
usually a string, but it can also be a Type or TypeName object.
|
||||
"""
|
||||
if not isinstance(type, Type):
|
||||
type = self.prog_.type(type)
|
||||
return Object(self.prog_, type, value=self._value,
|
||||
address=self.address_)
|
||||
|
||||
def address_of_(self) -> 'Object':
|
||||
"""
|
||||
Return an object pointing to this object. Corresponds to the address-of
|
||||
|
@ -2,7 +2,7 @@ import math
|
||||
import operator
|
||||
import tempfile
|
||||
|
||||
from drgn import container_of, NULL, Object, Program
|
||||
from drgn import cast, container_of, NULL, Object, Program
|
||||
from drgn.internal.corereader import CoreReader
|
||||
from drgn.type import IntType, StructType, TypedefType
|
||||
from tests.test_type import color_type, point_type
|
||||
@ -52,12 +52,12 @@ class TestObject(TypeIndexTestCase):
|
||||
|
||||
def test_cast(self):
|
||||
obj = Object(self.prog, TYPES['int'], value=-1)
|
||||
cast_obj = obj.cast_('unsigned int')
|
||||
cast_obj = cast('unsigned int', obj)
|
||||
self.assertEqual(cast_obj,
|
||||
Object(self.prog, TYPES['unsigned int'], value=2**32 - 1))
|
||||
|
||||
obj = Object(self.prog, TYPES['double'], value=1.0)
|
||||
self.assertRaises(TypeError, obj.cast_, self.type_index.pointer(TYPES['int']))
|
||||
self.assertRaises(TypeError, cast, self.type_index.pointer(TYPES['int']), obj)
|
||||
|
||||
def test_str(self):
|
||||
obj = Object(self.prog, TYPES['int'], value=1)
|
||||
@ -170,7 +170,7 @@ class TestObject(TypeIndexTestCase):
|
||||
with self.assertRaises(ValueError):
|
||||
obj.member_('foo')
|
||||
|
||||
cast_obj = obj.cast_('unsigned long')
|
||||
cast_obj = cast('unsigned long', obj)
|
||||
self.assertEqual(cast_obj,
|
||||
Object(self.prog, TYPES['unsigned long'], value=0))
|
||||
self.assertRaises(TypeError, obj.__index__)
|
||||
|
Loading…
Reference in New Issue
Block a user