Пример #1
0
def rb_prev(node: Object) -> Object:
    """
    Return the previous node (in sort order) before a red-black node, or
    ``NULL`` if the node is the first node in the tree or is empty.

    :param node: ``struct rb_node *``
    :return: ``struct rb_node *``
    """
    node = node.read_()

    if RB_EMPTY_NODE(node):
        return NULL(node.prog_, node.type_)

    next = node.rb_left.read_()
    if next:
        node = next
        while True:
            next = node.rb_right.read_()
            if not next:
                return node
            node = next

    parent = rb_parent(node).read_()
    while parent and node == parent.rb_left:
        node = parent
        parent = rb_parent(node).read_()
    return parent
Пример #2
0
def list_empty(head: Object) -> bool:
    """
    Return whether a list is empty.

    :param head: ``struct list_head *``
    """
    head = head.read_()
    return head.next == head
Пример #3
0
def list_is_singular(head: Object) -> bool:
    """
    Return whether a list has only one element.

    :param head: ``struct list_head *``
    """
    head = head.read_()
    next = head.next
    return next != head and next == head.prev
Пример #4
0
def list_for_each_reverse(head: Object) -> Iterator[Object]:
    """
    Iterate over all of the nodes in a list in reverse order.

    :param head: ``struct list_head *``
    :return: Iterator of ``struct list_head *`` objects.
    """
    head = head.read_()
    pos = head.prev.read_()
    while pos != head:
        yield pos
        pos = pos.prev.read_()
Пример #5
0
 def test_cast_primitive_value(self):
     obj = Object(self.prog, "long", value=2 ** 32 + 1)
     self.assertIdentical(cast("int", obj), Object(self.prog, "int", value=1))
     self.assertIdentical(
         cast("int", obj.read_()), Object(self.prog, "int", value=1)
     )
     self.assertIdentical(
         cast("const int", Object(self.prog, "int", value=1)),
         Object(self.prog, "const int", value=1),
     )
     self.assertRaisesRegex(
         TypeError,
         "cannot cast to 'struct point'",
         cast,
         self.point_type,
         Object(self.prog, "int", value=1),
     )
Пример #6
0
 def test_address_of(self):
     obj = Object(self.prog, "int", address=0xFFFF0000)
     self.assertIdentical(
         obj.address_of_(), Object(self.prog, "int *", value=0xFFFF0000)
     )
     obj = obj.read_()
     self.assertRaisesRegex(
         ValueError, "cannot take address of value", obj.address_of_
     )
     obj = Object(self.prog, "int", address=0xFFFF0000, bit_field_size=4)
     self.assertRaisesRegex(
         ValueError, "cannot take address of bit field", obj.address_of_
     )
     obj = Object(self.prog, "int", address=0xFFFF0000, bit_offset=4)
     self.assertRaisesRegex(
         ValueError, "cannot take address of bit field", obj.address_of_
     )
Пример #7
0
 def test_read_struct_bit_offset(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) + b"\0"
                 prog = mock_program(segments=[MockMemorySegment(buf, 0)])
                 obj = Object(
                     prog,
                     prog.struct_type(
                         None,
                         (bit_offset + bit_size + 7) // 8,
                         (
                             TypeMember(
                                 Object(
                                     prog,
                                     prog.int_type(
                                         "unsigned long long",
                                         8,
                                         False,
                                         byteorder,
                                     ),
                                     bit_field_size=bit_size,
                                 ),
                                 "x",
                                 bit_offset=bit_offset,
                             ),
                         ),
                     ),
                     address=0,
                 )
                 self.assertEqual(obj.x.value_(), value & ((1 << bit_size) - 1))
                 self.assertEqual(
                     obj.x.read_().value_(), value & ((1 << bit_size) - 1)
                 )
                 self.assertEqual(
                     obj.read_().x.value_(), value & ((1 << bit_size) - 1)
                 )
Пример #8
0
def list_first_entry_or_null(head: Object, type: Union[str, Type],
                             member: str) -> Object:
    """
    Return the first entry in a list or ``NULL`` if the list is empty.

    See also :func:`list_first_entry()`.

    :param head: ``struct list_head *``
    :param type: Entry type.
    :param member: Name of list node member in entry type.
    :return: ``type *``
    """
    head = head.read_()
    pos = head.next.read_()
    if pos == head:
        return NULL(head.prog_, head.prog_.pointer_type(head.prog_.type(type)))
    else:
        return container_of(pos, type, member)
Пример #9
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,
            )
Пример #10
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)",
        )
Пример #11
0
    def test_member(self):
        reference = Object(self.prog, self.point_type, address=0xFFFF0000)
        unnamed_reference = Object(
            self.prog,
            self.prog.struct_type(
                "point",
                8,
                (
                    TypeMember(
                        self.prog.struct_type(None, 8, self.point_type.members), None
                    ),
                ),
            ),
            address=0xFFFF0000,
        )
        ptr = Object(
            self.prog, self.prog.pointer_type(self.point_type), value=0xFFFF0000
        )
        for obj in [reference, unnamed_reference, ptr]:
            self.assertIdentical(
                obj.member_("x"), Object(self.prog, "int", address=0xFFFF0000)
            )
            self.assertIdentical(obj.member_("x"), obj.x)
            self.assertIdentical(
                obj.member_("y"), Object(self.prog, "int", address=0xFFFF0004)
            )
            self.assertIdentical(obj.member_("y"), obj.y)

            self.assertRaisesRegex(
                LookupError, "'struct point' has no member 'z'", obj.member_, "z"
            )
            self.assertRaisesRegex(
                AttributeError, "'struct point' has no member 'z'", getattr, obj, "z"
            )

        obj = reference.read_()
        self.assertIdentical(obj.x, Object(self.prog, "int", value=0))
        self.assertIdentical(obj.y, Object(self.prog, "int", value=1))

        obj = Object(self.prog, "int", value=1)
        self.assertRaisesRegex(
            TypeError, "'int' is not a structure, union, or class", obj.member_, "x"
        )
        self.assertRaisesRegex(AttributeError, "no attribute", getattr, obj, "x")
Пример #12
0
def validate_list_for_each(head: Object) -> Iterator[Object]:
    """
    Like :func:`list_for_each()`, but validates the list like
    :func:`validate_list()` while iterating.

    :param head: ``struct list_head *``
    :raises ValidationError: if the list is invalid
    """
    head = head.read_()
    pos = head.next.read_()
    while pos != head:
        yield pos
        next = pos.next.read_()
        next_prev = next.prev.read_()
        if next_prev != pos:
            raise ValidationError(
                f"{pos.format_(dereference=False, symbolize=False)}"
                f" next {next.format_(dereference=False, symbolize=False, type_name=False)}"
                f" has prev {next_prev.format_(dereference=False, symbolize=False, type_name=False)}"
            )
        pos = next
Пример #13
0
    def test_subscript(self):
        arr = Object(self.prog, "int [4]", address=0xFFFF0000)
        incomplete_arr = Object(self.prog, "int []", address=0xFFFF0000)
        ptr = Object(self.prog, "int *", value=0xFFFF0000)
        for obj in [arr, incomplete_arr, ptr]:
            for i in range(5):
                self.assertIdentical(
                    obj[i], Object(self.prog, "int", address=0xFFFF0000 + 4 * i)
                )
                if i < 4:
                    self.assertIdentical(
                        obj[i].read_(), Object(self.prog, "int", value=i)
                    )
                else:
                    self.assertRaises(FaultError, obj[i].read_)

        obj = arr.read_()
        for i in range(4):
            self.assertIdentical(obj[i], Object(self.prog, "int", value=i))
        self.assertRaisesRegex(OutOfBoundsError, "out of bounds", obj.__getitem__, 4)
        obj = Object(self.prog, "int", value=0)
        self.assertRaises(TypeError, obj.__getitem__, 0)