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_ )
def print_mlx5e_encap_entry(e): # print(e) print(e.encap_header) x = Object(prog, 'unsigned char *', address=e.encap_header.address_of_()) print_udphdr(x) print("encap_size: %d" % e.encap_size) # for i in range(e.encap_size): # print("%#x " % e.encap_header[i]) print("mlx5e_encap_entry %lx" % e.value_()) print(e.m_neigh) print_tun(e.tun_info) print("encap_id %lx" % e.encap_id.value_())
def test_bool(self): self.assertTrue(Object(self.prog, "int", value=-1)) self.assertFalse(Object(self.prog, "int", value=0)) self.assertTrue(Object(self.prog, "unsigned int", value=1)) self.assertFalse(Object(self.prog, "unsigned int", value=0)) self.assertTrue(Object(self.prog, "double", value=3.14)) self.assertFalse(Object(self.prog, "double", value=0.0)) self.assertTrue(Object(self.prog, "int *", value=0xFFFF0000)) self.assertFalse(Object(self.prog, "int *", value=0x0)) self.assertTrue(Object(self.prog, "int []", address=0)) self.assertRaisesRegex( TypeError, "cannot convert 'struct point' to bool", bool, Object(self.prog, self.point_type, address=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_()
def print_tunnel_mapping(item): print("mapping_item %lx" % item, end='\t') print("cnt: %d" % item.cnt, end='\t') print("id (tunnel_mapping): %d" % item.id, end='\t') key = Object(prog, 'struct tunnel_match_key', address=item.data.address_of_()) # print(key) print("tunnel: keyid: %x" % key.enc_key_id.keyid, end=' ') print("ipv4 src: %s" % ipv4(ntohl(key.enc_ipv4.src.value_())), end=' ') print("dst: %s" % ipv4(ntohl(key.enc_ipv4.dst.value_())), end=' ') print("ifindex: %d" % key.filter_ifindex)
def test_offsetof(self): self.assertEqual(offsetof(self.line_segment_type, "b"), 8) self.assertEqual(offsetof(self.line_segment_type, "a.y"), 4) self.assertRaisesRegex( LookupError, "'struct line_segment' has no member 'c'", offsetof, self.line_segment_type, "c.x", ) small_point_type = self.prog.struct_type( "small_point", 1, ( TypeMember( Object(self.prog, self.prog.int_type("int", 4, True), bit_field_size=4), "x", 0, ), TypeMember( Object(self.prog, self.prog.int_type("int", 4, True), bit_field_size=4), "y", 4, ), ), ) self.assertEqual(offsetof(small_point_type, "x"), 0) self.assertRaisesRegex( ValueError, "member is not byte-aligned", offsetof, small_point_type, "y", )
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))
def test_incomplete(self): # It's valid to create references with incomplete type, but not to read # from them. obj = Object(self.prog, self.prog.struct_type("foo"), address=0) self.assertRaisesRegex( TypeError, "cannot read object with incomplete structure type", obj.value_ ) self.assertRaisesRegex( TypeError, "cannot read object with incomplete structure type", obj.read_ ) self.assertRaises(TypeError, sizeof, obj) obj = Object(self.prog, self.prog.union_type("foo"), address=0) self.assertRaisesRegex( TypeError, "cannot read object with incomplete union type", obj.value_ ) self.assertRaisesRegex( TypeError, "cannot read object with incomplete union type", obj.read_ ) obj = Object(self.prog, self.prog.enum_type("foo"), address=0) self.assertRaisesRegex( TypeError, "cannot read object with incomplete enumerated type", obj.value_ ) self.assertRaisesRegex( TypeError, "cannot read object with incomplete enumerated type", obj.read_ ) obj = Object( self.prog, self.prog.array_type(self.prog.int_type("int", 4, True)), address=0, ) self.assertRaisesRegex( TypeError, "cannot read object with incomplete array type", obj.value_ ) self.assertRaisesRegex( TypeError, "cannot read object with incomplete array type", obj.read_ )
def test_constant(self): self.objects.append( MockObject("PAGE_SIZE", self.prog.int_type("int", 4, True), value=4096) ) self.assertIdentical( self.prog["PAGE_SIZE"], Object(self.prog, self.prog.int_type("int", 4, True), value=4096), ) self.assertIdentical( self.prog.object("PAGE_SIZE", FindObjectFlags.CONSTANT), self.prog["PAGE_SIZE"], ) self.assertTrue("PAGE_SIZE" in self.prog)
def test_function(self): mock_obj = MockObject('func', function_type(void_type(), (), False), address=0xffff0000) prog = mock_program(objects=[mock_obj]) self.assertEqual( prog['func'], Object(prog, function_type(void_type(), (), False), address=0xffff0000)) self.assertEqual(prog.object('func', FindObjectFlags.FUNCTION), prog['func']) self.assertTrue('func' in prog)
def test_void(self): obj = Object(self.prog, self.prog.void_type(), address=0) self.assertIs(obj.prog_, self.prog) self.assertIdentical(obj.type_, self.prog.void_type()) self.assertEqual(obj.address_, 0) self.assertEqual(obj.bit_offset_, 0) self.assertIsNone(obj.bit_field_size_) self.assertRaisesRegex( TypeError, "cannot read object with void type", obj.value_ ) self.assertRaisesRegex( TypeError, "cannot read object with void type", obj.read_ ) self.assertRaises(TypeError, sizeof, obj)
def test_variable(self): self.objects.append( MockObject( "counter", self.prog.int_type("int", 4, True), address=0xFFFF0000 ) ) self.assertIdentical( self.prog["counter"], Object(self.prog, self.prog.int_type("int", 4, True), address=0xFFFF0000), ) self.assertIdentical( self.prog.object("counter", FindObjectFlags.VARIABLE), self.prog["counter"] ) self.assertTrue("counter" in self.prog)
def pfn_to_virt(prog_or_pfn, pfn=None): """ .. c:function:: void *pfn_to_virt(unsigned long pfn) Get the directly mapped virtual address of the given page frame number (PFN). This can take the PFN as an :class:`Object`, or a :class:`Program` and the PFN as an ``int``. """ if pfn is None: prog = prog_or_pfn.prog_ pfn = prog_or_pfn.value_() else: prog = prog_or_pfn return Object(prog, "void *", value=(pfn << 12) + _page_offset(prog))
def test_function(self): mock_obj = MockObject("func", function_type(void_type(), (), False), address=0xFFFF0000) prog = mock_program(objects=[mock_obj]) self.assertEqual( prog["func"], Object(prog, function_type(void_type(), (), False), address=0xFFFF0000), ) self.assertEqual(prog.object("func", FindObjectFlags.FUNCTION), prog["func"]) self.assertTrue("func" in prog)
def print_indr_setup_block_ht(block): print(block) print(block.dev.name.string_().decode()) cb_list = block.cb_list # print(cb_list) for e in list_for_each_entry('struct flow_indr_block_cb', cb_list.address_of_(), 'list'): print(e) print(address_to_name(hex(e.cb))) priv = Object(prog, "struct mlx5e_rep_priv", address=e.cb_priv.address_of_()) # print(priv) print("mlx5e_rep_priv %lx" % e.cb_priv.address_of_())
def print_userspace(nlattr): print('\tOVS_ACTION_ATTR_USERSPACE') remaining = nlattr.nla_len.value_() # print("remaining: %x" % remaining) addr = nla_data(nlattr) nlattr = Object(prog, 'struct nlattr', address=addr) nla_type = nlattr.nla_type remaining -= NLA_HDRLEN while remaining > 0: if nlattr.nla_type == prog['OVS_USERSPACE_ATTR_PID']: # 1 data_addr = nla_data(nlattr) len = nlattr.nla_len.value_() pid = Object(prog, 'unsigned int', address=data_addr) print("\tOVS_USERSPACE_ATTR_PID: %x" % pid) addr += len nlattr = Object(prog, 'struct nlattr', address=addr) # print(nlattr) remaining -= len # print("remaining 2: %x" % remaining) elif nlattr.nla_type == prog['OVS_USERSPACE_ATTR_USERDATA']: # 2 data_addr = nla_data(nlattr) len = nlattr.nla_len.value_() addr += len nlattr = Object(prog, 'struct nlattr', address=addr) # print(nlattr) remaining -= len elif nlattr.nla_type == prog['OVS_USERSPACE_ATTR_ACTIONS']: # 4 len = nlattr.nla_len.value_() remaining -= len # print("remaining 3: %x" % remaining) if remaining == 0: break
def print_mlx5e_encap_entry(e): print("--- mlx5e_encap_entry ---") # print(e) # print("remote_ifindex: %d" % e.remote_ifindex) print("out_dev: %s" % e.out_dev.name.string_().decode()) print("route_dev_ifindex: %s" % e.route_dev_ifindex) # print(e.encap_header) x = Object(prog, 'unsigned char *', address=e.encap_header.address_of_()) print_vxlan_udphdr(x) print("encap_size: %d" % e.encap_size) # for i in range(e.encap_size): # print("%#x " % e.encap_header[i]) print("mlx5e_encap_entry %lx" % e.value_()) print_tun(e.tun_info) print("--- end ---")
def print_eventpoll(file): epoll = file.private_data epoll = Object(prog, "struct eventpoll", address=file.private_data) rb_root = epoll.rbr.rb_root print("eventpoll\t", end='') # print(epoll) for node in rbtree_inorder_for_each_entry("struct epitem", rb_root, "rbn"): print("%d" % node.ffd.fd.value_(), end=' ') # print(node.ffd.file.f_op.poll) # sock = Object(prog, "struct socket", address=node.ffd.file.private_data) # print(sock.ops.poll) print('')
def test_non_scalar_bit_offset(self): obj = Object( self.prog, self.prog.struct_type( "weird", 9, (TypeMember(self.point_type, "point", bit_offset=1),) ), address=0xFFFF0000, ) self.assertRaisesRegex( ValueError, "non-scalar must be byte-aligned", obj.member_, "point" ) self.assertRaisesRegex( ValueError, "non-scalar must be byte-aligned", Object, self.prog, self.point_type, address=0xFFFF0000, bit_offset=1, ) self.assertIdentical( Object(self.prog, self.point_type, address=0xFFFF0000, bit_offset=32), Object(self.prog, self.point_type, address=0xFFFF0004), )
def test_array(self): obj = Object(self.prog, "int [2]", value=[1, 2]) self.assertFalse(obj.absent_) self.assertIsNone(obj.address_) self.assertIdentical(obj[0], Object(self.prog, "int", value=1)) self.assertIdentical(obj[1], Object(self.prog, "int", value=2)) self.assertIdentical( Object(self.prog, "int [2]", value=[]), Object(self.prog, "int [2]", value=[0, 0]), ) self.assertRaisesRegex( TypeError, "must be iterable", Object, self.prog, "int [1]", value=1 ) self.assertRaisesRegex( ValueError, "too many items in array value", Object, self.prog, "int [1]", value=[1, 2], )
def per_cpu(var: Object, cpu: IntegerLike) -> Object: """ Return the per-CPU variable for a given CPU. >>> print(repr(prog["runqueues"])) Object(prog, 'struct rq', address=0x278c0) >>> per_cpu(prog["runqueues"], 6).curr.comm (char [16])"python3" :param var: Per-CPU variable, i.e., ``type __percpu`` (not a pointer; use :func:`per_cpu_ptr()` for that). :param cpu: CPU number. :return: ``type`` object. """ return per_cpu_ptr(var.address_of_(), cpu)[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), )
def virt_to_pfn(prog_or_addr, addr=None): """ .. c:function:: unsigned long virt_to_pfn(void *addr) Get the page frame number (PFN) of a directly mapped virtual address. This can take the address as an :class:`Object`, or a :class:`Program` and the address as an ``int``. """ if addr is None: prog = prog_or_addr.prog_ addr = prog_or_addr.value_() else: prog = prog_or_addr return Object(prog, "unsigned long", value=(addr - _page_offset(prog)) >> 12)
def mock_object_find(prog, name, flags, filename): if filename: return None for obj in objects: if obj.name == name: if obj.value is not None: if flags & FindObjectFlags.CONSTANT: break elif obj.type.kind == TypeKind.FUNCTION: if flags & FindObjectFlags.FUNCTION: break elif flags & FindObjectFlags.VARIABLE: break else: return None return Object(prog, obj.type, address=obj.address, value=obj.value)
def test_cast_compound_value(self): obj = Object(self.prog, self.point_type, address=0xFFFF0000).read_() self.assertRaisesRegex( TypeError, "cannot cast to 'struct point'", cast, self.point_type, obj, ) self.assertRaisesRegex( TypeError, "cannot convert 'struct point' to 'enum color'", cast, self.color_type, obj, )
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)
def _call_one(self, obj: drgn.Object) -> None: raw = self.args.raw nosym = self.args.nosymbolize if self.args.RAW: raw = True nosym = True print( obj.format_(dereference=self.args.dereference, char=self.args.char, symbolize=not nosym, members_same_line=self.args.sameline, type_name=not raw, member_type_names=not raw, element_type_names=not raw, member_names=not self.args.RAW, element_indices=not self.args.RAW))
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)
def test_function(self): self.objects.append( MockObject( "func", self.prog.function_type(self.prog.void_type(), (), False), address=0xFFFF0000, )) self.assertEqual( self.prog["func"], Object( self.prog, self.prog.function_type(self.prog.void_type(), (), False), address=0xFFFF0000, ), ) self.assertEqual(self.prog.object("func", FindObjectFlags.FUNCTION), self.prog["func"]) self.assertTrue("func" in self.prog)
def test_repr(self): m = TypeMember(self.prog.void_type, name="foo") self.assertEqual( repr(m), "TypeMember(prog.type('void'), name='foo', bit_offset=0)") m = TypeMember(self.prog.void_type) self.assertEqual(repr(m), "TypeMember(prog.type('void'), bit_offset=0)") m = TypeMember( Object(self.prog, self.prog.int_type("int", 4, True), bit_field_size=1)) self.assertEqual( repr(m), "TypeMember(Object(prog, 'int', bit_field_size=1), bit_offset=0)") m = TypeMember(lambda: None) self.assertRaises(TypeError, repr, m)