Ejemplo n.º 1
0
    def test_array(self):
        segment = bytearray()
        for i in range(10):
            segment.extend(i.to_bytes(4, "little"))
        self.add_memory_segment(segment, virt_addr=0xFFFF0000)
        obj = Object(self.prog, "int [5]", address=0xFFFF0000)
        self.assertEqual(obj.value_(), [0, 1, 2, 3, 4])
        self.assertEqual(sizeof(obj), 20)

        obj = Object(self.prog, "int [2][5]", address=0xFFFF0000)
        self.assertEqual(obj.value_(), [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])

        obj = Object(self.prog, "int [2][2][2]", address=0xFFFF0000)
        self.assertEqual(obj.value_(), [[[0, 1], [2, 3]], [[4, 5], [6, 7]]])
Ejemplo n.º 2
0
    def test_float(self):
        obj = Object(self.prog, "double", value=3.14)
        self.assertIs(obj.prog_, self.prog)
        self.assertIdentical(obj.type_, self.prog.type("double"))
        self.assertFalse(obj.absent_)
        self.assertIsNone(obj.address_)
        self.assertEqual(obj.value_(), 3.14)
        self.assertEqual(repr(obj), "Object(prog, 'double', value=3.14)")

        obj = Object(self.prog, "double", value=-100.0)
        self.assertIdentical(Object(self.prog, "double", value=-100), obj)

        self.assertRaisesRegex(
            TypeError,
            "'double' value must be number",
            Object,
            self.prog,
            "double",
            value={},
        )

        self.assertEqual(Object(self.prog, "double", value=math.e).value_(), math.e)
        self.assertEqual(
            Object(self.prog, "float", value=math.e).value_(),
            struct.unpack("f", struct.pack("f", math.e))[0],
        )
Ejemplo n.º 3
0
 def test_read_float(self):
     pi32 = struct.unpack("f", struct.pack("f", math.pi))[0]
     for bit_size in [32, 64]:
         for bit_offset in range(8):
             for byteorder in ["little", "big"]:
                 if bit_size == 64:
                     fmt = "<d"
                     expected = math.pi
                 else:
                     fmt = "<f"
                     expected = pi32
                 tmp = int.from_bytes(struct.pack(fmt, math.pi), "little")
                 if byteorder == "little":
                     tmp <<= bit_offset
                 else:
                     tmp <<= (8 - bit_size - bit_offset) % 8
                 buf = tmp.to_bytes((bit_size + bit_offset + 7) // 8, byteorder)
                 prog = mock_program(segments=[MockMemorySegment(buf, 0)])
                 obj = Object(
                     prog,
                     prog.float_type(
                         "double" if bit_size == 64 else "float",
                         bit_size // 8,
                         byteorder,
                     ),
                     address=0,
                     bit_offset=bit_offset,
                 )
                 self.assertEqual(obj.value_(), expected)
Ejemplo n.º 4
0
def is_a_nulls(pos: Object) -> bool:
    """
    Return whether a a pointer is a nulls marker.

    :param pos: ``struct hlist_nulls_node *``
    """
    return bool(pos.value_() & 1)
Ejemplo n.º 5
0
def print_flow_act(acts):
    nlattr = acts.actions[0]
    nla_type = nlattr.nla_type
    if nla_type == prog['OVS_ACTION_ATTR_OUTPUT']:
        addr = nlattr.address_of_().value_() + prog.type('struct nlattr').size
        port = Object(prog, 'int', address=addr)
        print("\toutput port: %d" % port.value_())
Ejemplo n.º 6
0
Archivo: slab.py Proyecto: osandov/drgn
 def _slub_get_freelist(freelist: Object,
                        freelist_set: Set[int]) -> None:
     # In SLUB, the freelist is a linked list with the next pointer
     # located at ptr + slab_cache->offset.
     ptr = freelist.value_()
     while ptr:
         freelist_set.add(ptr)
         ptr = prog.read_word(ptr + freelist_offset)
Ejemplo n.º 7
0
    def test_unsigned(self):
        obj = Object(self.prog, "unsigned int", value=2 ** 32 - 1)
        self.assertIs(obj.prog_, self.prog)
        self.assertIdentical(obj.type_, self.prog.type("unsigned int"))
        self.assertFalse(obj.absent_)
        self.assertIsNone(obj.address_)
        self.assertIsNone(obj.bit_offset_)
        self.assertIsNone(obj.bit_field_size_)
        self.assertEqual(obj.value_(), 2 ** 32 - 1)
        self.assertEqual(repr(obj), "Object(prog, 'unsigned int', value=4294967295)")

        self.assertIdentical(Object(self.prog, "unsigned int", value=-1), obj)
        self.assertIdentical(Object(self.prog, "unsigned int", value=2 ** 64 - 1), obj)
        self.assertIdentical(Object(self.prog, "unsigned int", value=2 ** 65 - 1), obj)
        self.assertIdentical(
            Object(self.prog, "unsigned int", value=2 ** 32 - 1 + 0.9), obj
        )

        self.assertRaisesRegex(
            TypeError,
            "'unsigned int' value must be number",
            Object,
            self.prog,
            "unsigned int",
            value="foo",
        )

        obj = Object(self.prog, "unsigned int", value=24, bit_field_size=4)
        self.assertIsNone(obj.bit_offset_)
        self.assertEqual(obj.bit_field_size_, 4)
        self.assertEqual(obj.value_(), 8)
        self.assertEqual(
            repr(obj), "Object(prog, 'unsigned int', value=8, bit_field_size=4)"
        )

        value = 12345678912345678989
        for bit_size in range(1, 65):
            self.assertEqual(
                Object(
                    self.prog,
                    "unsigned long long",
                    value=value,
                    bit_field_size=bit_size,
                ).value_(),
                value & ((1 << bit_size) - 1),
            )
Ejemplo n.º 8
0
def RB_EMPTY_NODE(node: Object) -> bool:
    """
    Return whether a red-black tree node is empty, i.e., not inserted in a
    tree.

    :param node: ``struct rb_node *``
    """
    return node.__rb_parent_color.value_() == node.value_()
Ejemplo n.º 9
0
    def test_basic(self):
        self.add_memory_segment((1000).to_bytes(4, "little"), virt_addr=0xFFFF0000)

        obj = Object(self.prog, "int", address=0xFFFF0000)
        self.assertIs(obj.prog_, self.prog)
        self.assertIdentical(obj.type_, self.prog.type("int"))
        self.assertFalse(obj.absent_)
        self.assertEqual(obj.address_, 0xFFFF0000)
        self.assertEqual(obj.bit_offset_, 0)
        self.assertIsNone(obj.bit_field_size_)
        self.assertEqual(obj.value_(), 1000)
        self.assertEqual(repr(obj), "Object(prog, 'int', address=0xffff0000)")

        self.assertIdentical(obj.read_(), Object(self.prog, "int", value=1000))

        obj = Object(
            self.prog, self.prog.int_type("sbe32", 4, True, "big"), address=0xFFFF0000
        )
        self.assertEqual(obj.value_(), -402456576)

        obj = Object(self.prog, "unsigned int", address=0xFFFF0000, bit_field_size=4)
        self.assertEqual(obj.bit_offset_, 0)
        self.assertEqual(obj.bit_field_size_, 4)
        self.assertEqual(obj.value_(), 8)
        self.assertEqual(
            repr(obj),
            "Object(prog, 'unsigned int', address=0xffff0000, bit_field_size=4)",
        )
        self.assertRaises(TypeError, sizeof, obj)

        obj = Object(
            self.prog,
            "unsigned int",
            address=0xFFFF0000,
            bit_field_size=4,
            bit_offset=4,
        )
        self.assertEqual(obj.bit_offset_, 4)
        self.assertEqual(obj.bit_field_size_, 4)
        self.assertEqual(obj.value_(), 14)
        self.assertEqual(
            repr(obj),
            "Object(prog, 'unsigned int', address=0xffff0000, bit_offset=4, bit_field_size=4)",
        )
Ejemplo n.º 10
0
    def test_signed(self):
        obj = Object(self.prog, "int", value=-4)
        self.assertIs(obj.prog_, self.prog)
        self.assertIdentical(obj.type_, self.prog.type("int"))
        self.assertFalse(obj.absent_)
        self.assertIsNone(obj.address_)
        self.assertIsNone(obj.bit_offset_)
        self.assertIsNone(obj.bit_field_size_)
        self.assertEqual(obj.value_(), -4)
        self.assertEqual(repr(obj), "Object(prog, 'int', value=-4)")

        self.assertIdentical(obj.read_(), obj)

        self.assertIdentical(Object(self.prog, "int", value=2 ** 32 - 4), obj)
        self.assertIdentical(Object(self.prog, "int", value=2 ** 64 - 4), obj)
        self.assertIdentical(Object(self.prog, "int", value=2 ** 128 - 4), obj)
        self.assertIdentical(Object(self.prog, "int", value=-4.6), obj)

        self.assertRaisesRegex(
            TypeError,
            "'int' value must be number",
            Object,
            self.prog,
            "int",
            value=b"asdf",
        )

        obj = Object(self.prog, "int", value=8, bit_field_size=4)
        self.assertIsNone(obj.bit_offset_)
        self.assertEqual(obj.bit_field_size_, 4)
        self.assertEqual(obj.value_(), -8)
        self.assertEqual(repr(obj), "Object(prog, 'int', value=-8, bit_field_size=4)")

        value = 12345678912345678989
        for bit_size in range(1, 65):
            tmp = value & ((1 << bit_size) - 1)
            mask = 1 << (bit_size - 1)
            tmp = (tmp ^ mask) - mask
            self.assertEqual(
                Object(
                    self.prog, "long", value=value, bit_field_size=bit_size
                ).value_(),
                tmp,
            )
Ejemplo n.º 11
0
def print_mod_hdr_key(key):
    actions = key.actions
    num_actions = key.num_actions
    for j in range(num_actions):
        p = Object(prog, 'void *', address=actions.value_())
        p = p.value_()
        l = socket.ntohl(p & 0xffffffff)
        h = socket.ntohl((p & 0xffffffff00000000) >> 32)
        parse_pedit(l, h)
        actions = actions + 8
Ejemplo n.º 12
0
 def test_pointer_typedef(self):
     obj = Object(
         self.prog,
         self.prog.typedef_type("INTP", self.prog.type("int *")),
         value=0xFFFF0000,
     )
     self.assertFalse(obj.absent_)
     self.assertIsNone(obj.address_)
     self.assertEqual(obj.value_(), 0xFFFF0000)
     self.assertEqual(repr(obj), "Object(prog, 'INTP', value=0xffff0000)")
Ejemplo n.º 13
0
def per_cpu_ptr(ptr: Object, cpu: IntegerLike) -> Object:
    """
    Return the per-CPU pointer for a given CPU.

    :param ptr: ``type __percpu *``
    :param cpu: CPU number.
    :return: ``type *``
    """
    offset = ptr.prog_["__per_cpu_offset"][cpu].value_()
    return Object(ptr.prog_, ptr.type_, value=ptr.value_() + offset)
Ejemplo n.º 14
0
def name_to_address(name):
    (status,
     output) = subprocess.getstatusoutput("grep -w " + name +
                                          " /proc/kallsyms | awk '{print $1}'")
    print("%d, %s" % (status, output))

    if status:
        return 0

    t = int(output, 16)
    p = Object(prog, 'void *', address=t)

    return p.value_()
Ejemplo n.º 15
0
    def test_struct(self):
        self.add_memory_segment(
            (
                (99).to_bytes(4, "little")
                + (-1).to_bytes(4, "little", signed=True)
                + (12345).to_bytes(4, "little")
                + (0).to_bytes(4, "little")
            ),
            virt_addr=0xFFFF0000,
        )
        self.types.append(self.point_type)
        obj = Object(self.prog, "struct point", address=0xFFFF0000)
        self.assertEqual(obj.value_(), {"x": 99, "y": -1})
        self.assertEqual(sizeof(obj), 8)

        type_ = self.prog.struct_type(
            "foo",
            16,
            (
                TypeMember(self.point_type, "point"),
                TypeMember(
                    self.prog.struct_type(
                        None,
                        8,
                        (
                            TypeMember(self.prog.int_type("int", 4, True), "bar"),
                            TypeMember(self.prog.int_type("int", 4, True), "baz", 32),
                        ),
                    ),
                    None,
                    64,
                ),
            ),
        )
        obj = Object(self.prog, type_, address=0xFFFF0000)
        self.assertEqual(
            obj.value_(), {"point": {"x": 99, "y": -1}, "bar": 12345, "baz": 0}
        )
Ejemplo n.º 16
0
def per_cpu_ptr(ptr: Object, cpu: IntegerLike) -> Object:
    """
    Return the per-CPU pointer for a given CPU.

    >>> prog["init_net"].loopback_dev.pcpu_refcnt
    (int *)0x2c980
    >>> per_cpu_ptr(prog["init_net"].loopback_dev.pcpu_refcnt, 7)
    *(int *)0xffff925e3ddec980 = 4

    :param ptr: Per-CPU pointer, i.e., ``type __percpu *``. For global
        variables, it's usually easier to use :func:`per_cpu()`.
    :param cpu: CPU number.
    :return: ``type *`` object.
    """
    offset = ptr.prog_["__per_cpu_offset"][cpu].value_()
    return Object(ptr.prog_, ptr.type_, value=ptr.value_() + offset)
Ejemplo n.º 17
0
 def test_compound_offset(self):
     value = {"n": 23, "x": 100, "y": -5}
     obj = Object(
         self.prog,
         self.prog.struct_type(
             None,
             12,
             (
                 TypeMember(self.prog.int_type("int", 4, True), "n"),
                 TypeMember(self.point_type, None, 32),
             ),
         ),
         value,
     )
     self.assertEqual(obj.value_(), value)
     self.assertIdentical(obj.x, Object(self.prog, "int", value=100))
     self.assertIdentical(obj.y, Object(self.prog, "int", value=-5))
Ejemplo n.º 18
0
def print_hmap(hmap_addr, struct_name, member):
    objs = []

    buckets = hmap_addr.buckets.value_()
    n = hmap_addr.n.value_()

    if n == 0:
        return objs


#     print("\n=== %s: buckets: %x, n: %d ===" % (struct_name, buckets, n))

    i = 0
    while 1:
        p = Object(prog, 'void *', address=buckets)
        if p.value_() == 0:
            buckets = buckets + 8
            continue

        data = container_of(p, "struct " + struct_name, member)
        objs.append(data)

        i += 1
        if i == n:
            return objs

        next = data.member_(member).next

        while next.value_() != 0:

            data = container_of(next, "struct " + struct_name, member)
            objs.append(data)

            i += 1
            if i == n:
                return objs

            next = data.member_(member).next

        buckets = buckets + 8

    return objs
Ejemplo n.º 19
0
 def test_read_unsigned(self):
     value = 12345678912345678989
     for bit_size in range(1, 65):
         for bit_offset in range(8):
             size = (bit_size + bit_offset + 7) // 8
             size_mask = (1 << (8 * size)) - 1
             for byteorder in ["little", "big"]:
                 if byteorder == "little":
                     tmp = value << bit_offset
                 else:
                     tmp = value << (8 - bit_size - bit_offset) % 8
                 tmp &= size_mask
                 buf = tmp.to_bytes(size, byteorder)
                 prog = mock_program(segments=[MockMemorySegment(buf, 0)])
                 obj = Object(
                     prog,
                     prog.int_type("unsigned long long", 8, False, byteorder),
                     address=0,
                     bit_field_size=bit_size,
                     bit_offset=bit_offset,
                 )
                 self.assertEqual(obj.value_(), value & ((1 << bit_size) - 1))
Ejemplo n.º 20
0
def for_each_onslab_object_in_slab(slab: drgn.Object) -> Iterable[drgn.Object]:
    assert sdb.type_canonical_name(slab.type_) == 'struct spl_kmem_slab *'
    cache = slab.sks_cache
    sks_size = spl_aligned_slab_size(cache)
    spl_obj_size = spl_aligned_obj_size(cache)

    for i in range(slab.sks_objs.value_()):
        obj = sdb.create_object('void *',
                                slab.value_() + sks_size + (i * spl_obj_size))
        #
        # If the sko_list of the object is empty, it means that
        # this object is not part of the slab's internal free list
        # and therefore it is allocated. NOTE: sko_list in the
        # actual code is not a list, but a link on a list. Thus,
        # the check below is not checking whether the "object
        # list" is empty for this slab, but rather whether the
        # link is part of any list.
        #
        sko = sko_from_obj(cache, obj)
        assert sko.sko_magic.value_() == 0x20202020  # SKO_MAGIC
        if linked_lists.is_list_empty(sko.sko_list):
            yield obj
Ejemplo n.º 21
0
 def _slub_get_freelist(freelist: Object, freelist_set: Set[int]) -> None:
     ptr = freelist.value_()
     while ptr:
         freelist_set.add(ptr)
         ptr = _freelist_dereference(ptr + freelist_offset)
Ejemplo n.º 22
0
            release = address_to_name(hex(release))
#             print("flow_block_cb release: %s" % release)

            cb_priv = Object(prog, 'struct mlx5e_rep_indr_block_priv', address=cb.cb_priv.value_())
#             print("mlx5e_rep_indr_block_priv %lx" % cb_priv.address_of_())
#             print(cb_priv)
    else:
        for cb in list_for_each_entry('struct tcf_block_cb', block.cb_list.address_of_(), 'list'):
            print(cb)
            func = cb.cb.value_()
            func = address_to_name(hex(func))
            print("tcf_block_cb cb: %s" % func)

            # ofed 4.7, cb is mlx5e_rep_indr_setup_block_cb
            priv = cb.cb_priv
            priv = Object(prog, 'struct mlx5e_rep_indr_block_priv', address=priv.value_())
#             print(priv)

            # on ofed 4.6, priv is the pointer of struct mlx5e_priv

    print("\n%20s ingress_sched_data %20x\n" % (name, addr))

    chain_list_addr = block.chain_list.address_of_()
    for chain in list_for_each_entry('struct tcf_chain', chain_list_addr, 'list'):
        if (chain.value_() == 0):
            print("chain 0, continue")
            continue
        print("tcf_chain %lx" % chain.value_())
        print("tcf_block %lx" % chain.block.value_())
        print("chain index: %d, 0x%x" % (chain.index, chain.index))
        print("chain refcnt: %d" % (chain.refcnt))
Ejemplo n.º 23
0
def print_chain_mapping(item):
    print("mapping_item %lx" % item, end='\t')
    print("cnt: %d" % item.cnt, end='\t')
    print("id (chain_mapping): %d" % item.id, end='\t')
    data = Object(prog, 'int *', address=item.data.address_of_())
    print("data (chain): 0x%x" % data.value_())
Ejemplo n.º 24
0
    def test_compound(self):
        obj = Object(self.prog, self.point_type, value={"x": 100, "y": -5})
        self.assertIdentical(obj.x, Object(self.prog, "int", value=100))
        self.assertIdentical(obj.y, Object(self.prog, "int", value=-5))

        self.assertIdentical(
            Object(self.prog, self.point_type, value={}),
            Object(self.prog, self.point_type, value={"x": 0, "y": 0}),
        )

        value = {
            "a": {"x": 1, "y": 2},
            "b": {"x": 3, "y": 4},
        }
        obj = Object(self.prog, self.line_segment_type, value=value)
        self.assertIdentical(
            obj.a, Object(self.prog, self.point_type, value={"x": 1, "y": 2})
        )
        self.assertIdentical(
            obj.b, Object(self.prog, self.point_type, value={"x": 3, "y": 4})
        )
        self.assertEqual(obj.value_(), value)

        invalid_struct = self.prog.struct_type(
            "foo",
            4,
            (
                TypeMember(self.prog.int_type("short", 2, True), "a"),
                # Straddles the end of the structure.
                TypeMember(self.prog.int_type("int", 4, True), "b", 16),
                # Beyond the end of the structure.
                TypeMember(self.prog.int_type("int", 4, True), "c", 32),
            ),
        )

        Object(self.prog, invalid_struct, value={"a": 0})
        self.assertRaisesRegex(
            OutOfBoundsError,
            "out of bounds of value",
            Object,
            self.prog,
            invalid_struct,
            value={"a": 0, "b": 4},
        )
        self.assertRaisesRegex(
            OutOfBoundsError,
            "out of bounds of value",
            Object,
            self.prog,
            invalid_struct,
            value={"a": 0, "c": 4},
        )

        self.assertRaisesRegex(
            TypeError,
            "must be dictionary or mapping",
            Object,
            self.prog,
            self.point_type,
            value=1,
        )
        self.assertRaisesRegex(
            TypeError,
            "member key must be string",
            Object,
            self.prog,
            self.point_type,
            value={0: 0},
        )
        self.assertRaisesRegex(
            TypeError,
            "must be number",
            Object,
            self.prog,
            self.point_type,
            value={"x": []},
        )
        self.assertRaisesRegex(
            LookupError,
            "has no member 'z'",
            Object,
            self.prog,
            self.point_type,
            value={"z": 999},
        )
Ejemplo n.º 25
0
def _entry_to_node(node: Object, internal_node: int) -> Object:
    return Object(node.prog_, node.type_, value=node.value_() & ~internal_node)
Ejemplo n.º 26
0
def _is_internal_node(node: Object, internal_node: int) -> bool:
    return (node.value_() & _RADIX_TREE_ENTRY_MASK) == internal_node
Ejemplo n.º 27
0
 def test_pointer(self):
     obj = Object(self.prog, "int *", value=0xFFFF0000)
     self.assertFalse(obj.absent_)
     self.assertIsNone(obj.address_)
     self.assertEqual(obj.value_(), 0xFFFF0000)
     self.assertEqual(repr(obj), "Object(prog, 'int *', value=0xffff0000)")
Ejemplo n.º 28
0
#!/usr/local/bin/drgn -k

from drgn.helpers.linux import *
from drgn import Object
import time
import sys
import os

sys.path.append("..")
import lib

gen = prog['init_net'].gen
id = prog['tcf_action_net_id']
print("tcf_action_net_id: %d" % id)
ptr = gen.ptr[id]
tcf_action_net = Object(prog, 'struct tcf_action_net', address=ptr.value_())
print("tcf_action_net %lx" % tcf_action_net.address_of_())

for cb in list_for_each_entry('struct tcf_action_egdev_cb', tcf_action_net.egdev_list.address_of_(), 'list'):
    print(cb)
    func = cb.cb.value_()
    func = lib.address_to_name(hex(func))
    print(func)
    priv = cb.cb_priv
    priv = Object(prog, 'struct mlx5e_priv', address=priv.value_())
    print(priv.netdev.name.string_().decode())
Ejemplo n.º 29
0
                             address=cb.cb_priv.value_())
#             print("mlx5e_rep_indr_block_priv %lx" % cb_priv.address_of_())
#             print(cb_priv)
    else:
        for cb in list_for_each_entry('struct tcf_block_cb',
                                      block.cb_list.address_of_(), 'list'):
            print(cb)
            func = cb.cb.value_()
            func = address_to_name(hex(func))
            print("tcf_block_cb cb: %s" % func)

            # ofed 4.7, cb is mlx5e_rep_indr_setup_block_cb
            priv = cb.cb_priv
            priv = Object(prog,
                          'struct mlx5e_rep_indr_block_priv',
                          address=priv.value_())
#             print(priv)

# on ofed 4.6, priv is the pointer of struct mlx5e_priv

    chain_list_addr = block.chain_list.address_of_()
    for chain in list_for_each_entry('struct tcf_chain', chain_list_addr,
                                     'list'):
        if (chain.value_() == 0):
            print("chain 0, continue")
            continue
        print("tcf_chain %lx, index: %d, %x, refcnt: %d, action_refcnt: %d" % \
             (chain, chain.index, chain.index, chain.refcnt, chain.action_refcnt))
        tcf_proto = chain.filter_chain
        while True:
            print("  tcf_proto %lx, protocol %x, prio %x" %       \
Ejemplo n.º 30
0
def sko_from_obj(cache: drgn.Object, obj: drgn.Object) -> drgn.Object:
    assert sdb.type_canonical_name(cache.type_) == 'struct spl_kmem_cache *'
    cache_obj_align = cache.skc_obj_align.value_()
    return sdb.create_object(
        'spl_kmem_obj_t *',
        obj.value_() + p2.p2roundup(object_size(cache), cache_obj_align))