def test_bad_thunk(self): t1 = struct_type('foo', 16, ((lambda: exec('raise Exception("test")'), 'bar'), )) with self.assertRaisesRegex(Exception, 'test'): t1.members t1 = struct_type('foo', 16, ((lambda: 0, 'bar'), )) with self.assertRaisesRegex(TypeError, 'type callable must return Type'): t1.members
def test_bad_thunk(self): t1 = struct_type("foo", 16, ((lambda: exec('raise Exception("test")'), "bar"), )) with self.assertRaisesRegex(Exception, "test"): t1.members t1 = struct_type("foo", 16, ((lambda: 0, "bar"), )) with self.assertRaisesRegex(TypeError, "type callable must return Type"): t1.members
def test_cycle(self): t1 = struct_type('foo', 8, ((lambda: pointer_type(8, t1), 'next'), )) t2 = struct_type('foo', 8, ((lambda: pointer_type(8, t2), 'next'), )) t3, t4 = (struct_type('foo', 8, ((lambda: pointer_type(8, t4), 'next'), )), struct_type('foo', 8, ((lambda: pointer_type(8, t3), 'next'), ))) self.assertEqual(t1, t2) self.assertEqual(t2, t3) self.assertEqual(t3, t4) self.assertEqual( repr(t1), "struct_type(tag='foo', size=8, members=((pointer_type(size=8, type=struct_type(tag='foo', ...)), 'next', 0, 0),))" )
def test_cycle2(self): t1 = struct_type('list_head', 16, ( (lambda: pointer_type(8, t1), 'next'), (lambda: pointer_type(8, t1), 'prev', 8), )) t2 = struct_type('list_head', 16, ( (lambda: pointer_type(8, t2), 'next'), (lambda: pointer_type(8, t2), 'prev', 8), )) self.assertEqual(t1, t2) self.assertEqual( repr(t1), "struct_type(tag='list_head', size=16, members=((pointer_type(size=8, type=struct_type(tag='list_head', ...)), 'next', 0, 0), (pointer_type(size=8, type=struct_type(tag='list_head', ...)), 'prev', 8, 0)))" )
def test_typedef(self): self.assertPrettyPrint(typedef_type('INT', int_type('int', 4, True)), 'typedef int INT') self.assertPrettyPrint( typedef_type('CINT', int_type('int', 4, True, Qualifiers.CONST)), 'typedef const int CINT') self.assertPrettyPrint( typedef_type('INT', int_type('int', 4, True), Qualifiers.CONST), 'const typedef int INT') self.assertPrettyPrint( typedef_type('string', pointer_type(8, int_type('char', 1, True))), 'typedef char *string') t = typedef_type( 'Point', struct_type(None, 8, ( (int_type('int', 4, True), 'x', 0), (int_type('int', 4, True), 'y', 4), ))) self.assertPrettyPrint( t, """\ typedef struct { int x; int y; } Point""")
def create_struct_type(name: str, member_names: List[str], member_types: List[drgn.Type]) -> drgn.Type: """ Creates a structure type given a list of member names and a list of types like this: ``` create_struct_type(<name>, [<name_a>, <name_b> ...], [<type_a>, <type_b>, ...]) ``` returns a C structure: ``` struct <name> { type_a name_a; type_b name_b; ... }; ``` """ assert len(member_names) == len(member_types) struct_size, bit_offset = 0, 0 member_list = [] for member_name, type_ in zip(member_names, member_types): member_tuple = (type_, member_name, bit_offset, 0) member_list.append(member_tuple) bit_offset += 8 * struct_size struct_size += type_.size return drgn.struct_type(name, struct_size, member_list)
def test_typedef(self): self.assertPrettyPrint(typedef_type("INT", int_type("int", 4, True)), "typedef int INT") self.assertPrettyPrint( typedef_type("CINT", int_type("int", 4, True, Qualifiers.CONST)), "typedef const int CINT", ) self.assertPrettyPrint( typedef_type("INT", int_type("int", 4, True), Qualifiers.CONST), "const typedef int INT", ) self.assertPrettyPrint( typedef_type("string", pointer_type(8, int_type("char", 1, True))), "typedef char *string", ) t = typedef_type( "Point", struct_type( None, 8, ( TypeMember(int_type("int", 4, True), "x", 0), TypeMember(int_type("int", 4, True), "y", 4), ), ), ) self.assertPrettyPrint( t, """\ typedef struct { int x; int y; } Point""", )
def test_infinite(self): f = lambda: struct_type('foo', 0, ((f, 'next'), )) self.assertEqual( repr(f()), "struct_type(tag='foo', size=0, members=((struct_type(tag='foo', ...), 'next', 0, 0),))" ) with self.assertRaisesRegex(RecursionError, 'maximum.*depth'): f() == f()
def test_infinite(self): f = lambda: struct_type("foo", 0, (TypeMember(f, "next"), )) self.assertEqual( repr(f()), "struct_type(tag='foo', size=0, members=(TypeMember(type=struct_type(tag='foo', ...), name='next', bit_offset=0),))", ) with self.assertRaisesRegex(RecursionError, "maximum.*depth"): f() == f()
def test_function_no_name(self): self.assertRaisesRegex( ValueError, "function must have name", str, struct_type( "foo", 8, ((function_type(int_type("int", 4, True), (), False), None),) ), )
def test_cycle(self): t1 = struct_type("foo", 8, (TypeMember(lambda: pointer_type(8, t1), "next"), )) t2 = struct_type("foo", 8, (TypeMember(lambda: pointer_type(8, t2), "next"), )) t3, t4 = ( struct_type("foo", 8, (TypeMember(lambda: pointer_type(8, t4), "next"), )), struct_type("foo", 8, (TypeMember(lambda: pointer_type(8, t3), "next"), )), ) self.assertEqual(t1, t2) self.assertEqual(t2, t3) self.assertEqual(t3, t4) self.assertEqual( repr(t1), "struct_type(tag='foo', size=8, members=(TypeMember(type=pointer_type(size=8, type=struct_type(tag='foo', ...)), name='next', bit_offset=0),))", )
def test_bit_field(self): point = struct_type('point', 4, ( (int_type('int', 4, True), 'x', 0, 4), (int_type('int', 4, True), 'y', 4, 8), )) self.assertPrettyPrint( point, """\ struct point { int x : 4; int y : 8; }""")
def test_cycle2(self): t1 = struct_type( "list_head", 16, ( TypeMember(lambda: pointer_type(8, t1), "next"), TypeMember(lambda: pointer_type(8, t1), "prev", 8), ), ) t2 = struct_type( "list_head", 16, ( TypeMember(lambda: pointer_type(8, t2), "next"), TypeMember(lambda: pointer_type(8, t2), "prev", 8), ), ) self.assertEqual(t1, t2) self.assertEqual( repr(t1), "struct_type(tag='list_head', size=16, members=(TypeMember(type=pointer_type(size=8, type=struct_type(tag='list_head', ...)), name='next', bit_offset=0), TypeMember(type=pointer_type(size=8, type=struct_type(tag='list_head', ...)), name='prev', bit_offset=8)))", )
def test_bit_field(self): point = struct_type( "point", 4, ( (int_type("int", 4, True), "x", 0, 4), (int_type("int", 4, True), "y", 4, 8), ), ) self.assertPrettyPrint( point, """\ struct point { int x : 4; int y : 8; }""", )
def test_struct(self): t = struct_type( "point", 8, ( TypeMember(int_type("int", 4, True), "x", 0), TypeMember(int_type("int", 4, True), "y", 32), ), ) self.assertEqual(t.kind, TypeKind.STRUCT) self.assertIsNone(t.primitive) self.assertEqual(t.language, DEFAULT_LANGUAGE) self.assertEqual(t.tag, "point") self.assertEqual(t.size, 8) self.assertEqual( t.members, ( TypeMember(int_type("int", 4, True), "x", 0, 0), TypeMember(int_type("int", 4, True), "y", 32, 0), ), ) self.assertTrue(t.is_complete()) self.assertEqual( t, struct_type( "point", 8, ( TypeMember(int_type("int", 4, True), "x", 0), TypeMember(int_type("int", 4, True), "y", 32), ), ), ) # Different tag. self.assertNotEqual( t, struct_type( "pt", 8, ( TypeMember(int_type("int", 4, True), "x", 0), TypeMember(int_type("int", 4, True), "y", 32), ), ), ) # Different size. self.assertNotEqual( t, struct_type( "point", 16, ( TypeMember(int_type("int", 4, True), "x", 0), TypeMember(int_type("int", 4, True), "y", 32), ), ), ) # One is anonymous. self.assertNotEqual( t, struct_type( None, 8, ( TypeMember(int_type("int", 4, True), "x", 0), TypeMember(int_type("int", 4, True), "y", 32), ), ), ) # Different members. self.assertNotEqual( t, struct_type( "point", 8, ( TypeMember(int_type("long", 8, True), "x", 0), TypeMember(int_type("long", 8, True), "y", 64), ), ), ) # Different number of members. self.assertNotEqual( t, struct_type( "point", 8, ( TypeMember(int_type("int", 4, True), "x", 0), TypeMember(int_type("int", 4, True), "y", 32), TypeMember(int_type("int", 4, True), "z", 64), ), ), ) # One member is anonymous. self.assertNotEqual( t, struct_type( "point", 8, ( TypeMember(int_type("int", 4, True), "x", 0), TypeMember(int_type("int", 4, True), None, 32), ), ), ) # One is incomplete. self.assertNotEqual(t, struct_type("point")) self.assertEqual( repr(t), "struct_type(tag='point', size=8, members=(TypeMember(type=int_type(name='int', size=4, is_signed=True), name='x', bit_offset=0), TypeMember(type=int_type(name='int', size=4, is_signed=True), name='y', bit_offset=32)))", ) self.assertEqual(sizeof(t), 8) t = struct_type( None, 8, ( TypeMember(int_type("int", 4, True), "x", 0), TypeMember(int_type("int", 4, True), "y", 32), ), ) self.assertEqual(t.kind, TypeKind.STRUCT) self.assertIsNone(t.primitive) self.assertIsNone(t.tag) self.assertEqual(t.size, 8) self.assertEqual( t.members, ( TypeMember(int_type("int", 4, True), "x", 0, 0), TypeMember(int_type("int", 4, True), "y", 32, 0), ), ) self.assertTrue(t.is_complete()) t = struct_type("color", 0, ()) self.assertEqual(t.kind, TypeKind.STRUCT) self.assertIsNone(t.primitive) self.assertEqual(t.tag, "color") self.assertEqual(t.size, 0) self.assertEqual(t.members, ()) self.assertTrue(t.is_complete()) self.assertEqual(repr(t), "struct_type(tag='color', size=0, members=())") t = struct_type("color") self.assertEqual(t.kind, TypeKind.STRUCT) self.assertIsNone(t.primitive) self.assertEqual(t.tag, "color") self.assertIsNone(t.size) self.assertIsNone(t.members) self.assertFalse(t.is_complete()) self.assertEqual(repr(t), "struct_type(tag='color', size=None, members=None)") t = struct_type(None, None, None) self.assertEqual(t.kind, TypeKind.STRUCT) self.assertIsNone(t.primitive) self.assertEqual(t.tag, None) self.assertIsNone(t.size) self.assertIsNone(t.members) self.assertFalse(t.is_complete()) self.assertEqual(repr(t), "struct_type(tag=None, size=None, members=None)") self.assertRaises(TypeError, struct_type, 4) self.assertRaisesRegex(ValueError, "must not have size", struct_type, "point", 8, None) self.assertRaisesRegex(ValueError, "must have size", struct_type, "point", None, ()) self.assertRaisesRegex(TypeError, "must be sequence or None", struct_type, "point", 8, 4) self.assertRaisesRegex(TypeError, "must be TypeMember", struct_type, "point", 8, (4, )) # Bit size. t = struct_type( "point", 8, ( TypeMember(int_type("int", 4, True), "x", 0, 4), TypeMember(int_type("int", 4, True), "y", 32, 4), ), ) self.assertEqual( t.members, ( TypeMember(int_type("int", 4, True), "x", 0, 4), TypeMember(int_type("int", 4, True), "y", 32, 4), ), )
def test_struct(self): t = struct_type('point', 8, ( (int_type('int', 4, True), 'x', 0), (int_type('int', 4, True), 'y', 32), )) self.assertEqual(t.kind, TypeKind.STRUCT) self.assertIsNone(t.primitive) self.assertEqual(t.tag, 'point') self.assertEqual(t.size, 8) self.assertEqual(t.members, ( (int_type('int', 4, True), 'x', 0, 0), (int_type('int', 4, True), 'y', 32, 0), )) self.assertTrue(t.is_complete()) self.assertEqual( t, struct_type('point', 8, ( (int_type('int', 4, True), 'x', 0), (int_type('int', 4, True), 'y', 32), ))) # Different tag. self.assertNotEqual( t, struct_type('pt', 8, ( (int_type('int', 4, True), 'x', 0), (int_type('int', 4, True), 'y', 32), ))) # Different size. self.assertNotEqual( t, struct_type('point', 16, ( (int_type('int', 4, True), 'x', 0), (int_type('int', 4, True), 'y', 32), ))) # One is anonymous. self.assertNotEqual( t, struct_type(None, 8, ( (int_type('int', 4, True), 'x', 0), (int_type('int', 4, True), 'y', 32), ))) # Different members. self.assertNotEqual( t, struct_type('point', 8, ( (int_type('long', 8, True), 'x', 0), (int_type('long', 8, True), 'y', 64), ))) # Different number of members. self.assertNotEqual( t, struct_type('point', 8, ( (int_type('int', 4, True), 'x', 0), (int_type('int', 4, True), 'y', 32), (int_type('int', 4, True), 'z', 64), ))) # One member is anonymous. self.assertNotEqual( t, struct_type('point', 8, ( (int_type('int', 4, True), 'x', 0), (int_type('int', 4, True), None, 32), ))) # One is incomplete. self.assertNotEqual(t, struct_type('point')) self.assertEqual( repr(t), "struct_type(tag='point', size=8, members=((int_type(name='int', size=4, is_signed=True), 'x', 0, 0), (int_type(name='int', size=4, is_signed=True), 'y', 32, 0)))" ) t = struct_type(None, 8, ( (int_type('int', 4, True), 'x', 0), (int_type('int', 4, True), 'y', 32), )) self.assertEqual(t.kind, TypeKind.STRUCT) self.assertIsNone(t.primitive) self.assertIsNone(t.tag) self.assertEqual(t.size, 8) self.assertEqual(t.members, ( (int_type('int', 4, True), 'x', 0, 0), (int_type('int', 4, True), 'y', 32, 0), )) self.assertTrue(t.is_complete()) t = struct_type('color', 0, ()) self.assertEqual(t.kind, TypeKind.STRUCT) self.assertIsNone(t.primitive) self.assertEqual(t.tag, 'color') self.assertEqual(t.size, 0) self.assertEqual(t.members, ()) self.assertTrue(t.is_complete()) self.assertEqual(repr(t), "struct_type(tag='color', size=0, members=())") t = struct_type('color') self.assertEqual(t.kind, TypeKind.STRUCT) self.assertIsNone(t.primitive) self.assertEqual(t.tag, 'color') self.assertIsNone(t.size) self.assertIsNone(t.members) self.assertFalse(t.is_complete()) self.assertEqual(repr(t), "struct_type(tag='color', size=None, members=None)") t = struct_type(None, None, None) self.assertEqual(t.kind, TypeKind.STRUCT) self.assertIsNone(t.primitive) self.assertEqual(t.tag, None) self.assertIsNone(t.size) self.assertIsNone(t.members) self.assertFalse(t.is_complete()) self.assertEqual(repr(t), "struct_type(tag=None, size=None, members=None)") self.assertRaises(TypeError, struct_type, 4) self.assertRaisesRegex(ValueError, 'must not have size', struct_type, 'point', 8, None) self.assertRaisesRegex(ValueError, 'must have size', struct_type, 'point', None, ()) self.assertRaisesRegex(TypeError, 'must be sequence or None', struct_type, 'point', 8, 4) self.assertRaisesRegex(TypeError, 'must be.*sequence', struct_type, 'point', 8, (4)) self.assertRaisesRegex(ValueError, 'must be.*sequence', struct_type, 'point', 8, ((), )) self.assertRaisesRegex(TypeError, 'must be string or None', struct_type, 'point', 8, ((int_type('int', 4, True), 4, 0), )) self.assertRaisesRegex(TypeError, 'must be integer', struct_type, 'point', 8, ((int_type('int', 4, True), 'x', None), )) self.assertRaisesRegex(TypeError, 'must be Type', struct_type, 'point', 8, ((None, 'x', 0), )) # Bit size. t = struct_type('point', 8, ( (int_type('int', 4, True), 'x', 0, 4), (int_type('int', 4, True), 'y', 32, 4), )) self.assertEqual(t.members, ( (int_type('int', 4, True), 'x', 0, 4), (int_type('int', 4, True), 'y', 32, 4), ))
union_type, ) coord_type = class_type( "coord", 12, ( (int_type("int", 4, True), "x", 0), (int_type("int", 4, True), "y", 32), (int_type("int", 4, True), "z", 64), ), ) point_type = struct_type( "point", 8, ( (int_type("int", 4, True), "x", 0), (int_type("int", 4, True), "y", 32), ), ) line_segment_type = struct_type("line_segment", 16, ( (point_type, "a"), (point_type, "b", 64), )) option_type = union_type("option", 4, ( (int_type("int", 4, True), "i"), (float_type("float", 4), "f"), )) color_type = enum_type("color", int_type("unsigned int", 4, False), (("RED", 0), ("GREEN", 1), ("BLUE", 2))) pid_type = typedef_type("pid_t", int_type("int", 4, True))
def test_struct(self): self.assertPrettyPrint( point_type, """\ struct point { int x; int y; }""", ) line_segment = struct_type( "line_segment", 16, ((point_type, "a", 0), (point_type, "b", 8),) ) self.assertPrettyPrint( line_segment, """\ struct line_segment { struct point a; struct point b; }""", ) anonymous_point = struct_type( None, 8, ((int_type("int", 4, True), "x", 0), (int_type("int", 4, True), "y", 4),), ) self.assertPrettyPrint( anonymous_point, """\ struct { int x; int y; }""", ) # Member with anonymous struct type. line_segment = struct_type( "line_segment", 16, ((anonymous_point, "a", 0), (anonymous_point, "b", 8),) ) self.assertPrettyPrint( line_segment, """\ struct line_segment { struct { int x; int y; } a; struct { int x; int y; } b; }""", ) # Unnamed member. point3 = struct_type( "point3", 0, ((anonymous_point, None, 0), (int_type("int", 4, True), "z", 8),), ) self.assertPrettyPrint( point3, """\ struct point3 { struct { int x; int y; }; int z; }""", )
DEFAULT_LANGUAGE = Language.C coord_type = class_type( "coord", 12, ( TypeMember(int_type("int", 4, True), "x", 0), TypeMember(int_type("int", 4, True), "y", 32), TypeMember(int_type("int", 4, True), "z", 64), ), ) point_type = struct_type( "point", 8, ( TypeMember(int_type("int", 4, True), "x", 0), TypeMember(int_type("int", 4, True), "y", 32), ), ) line_segment_type = struct_type( "line_segment", 16, (TypeMember(point_type, "a"), TypeMember(point_type, "b", 64))) option_type = union_type( "option", 4, ( TypeMember(int_type("int", 4, True), "i"), TypeMember(float_type("float", 4), "f"), ), ) color_type = enum_type(
def test_struct(self): self.assertPrettyPrint(point_type, """\ struct point { int x; int y; }""") line_segment = struct_type('line_segment', 16, ( (point_type, 'a', 0), (point_type, 'b', 8), )) self.assertPrettyPrint( line_segment, """\ struct line_segment { struct point a; struct point b; }""") anonymous_point = struct_type(None, 8, ( (int_type('int', 4, True), 'x', 0), (int_type('int', 4, True), 'y', 4), )) self.assertPrettyPrint(anonymous_point, """\ struct { int x; int y; }""") # Member with anonymous struct type. line_segment = struct_type('line_segment', 16, ( (anonymous_point, 'a', 0), (anonymous_point, 'b', 8), )) self.assertPrettyPrint( line_segment, """\ struct line_segment { struct { int x; int y; } a; struct { int x; int y; } b; }""") # Unnamed member. point3 = struct_type('point3', 0, ( (anonymous_point, None, 0), (int_type('int', 4, True), 'z', 8), )) self.assertPrettyPrint( point3, """\ struct point3 { struct { int x; int y; }; int z; }""")
def test_function_no_name(self): self.assertRaisesRegex( ValueError, 'function must have name', str, struct_type('foo', 8, ((function_type(int_type('int', 4, True), (), False), None), )))
def test_infinite(self): f = lambda: struct_type('foo', 0, ((f, 'next'), )) self.assertRaises(RecursionError, repr, f()) with self.assertRaisesRegex(RecursionError, 'maximum.*depth'): f() == f()
Object, Platform, PlatformFlags, Program, Type, TypeKind, enum_type, float_type, int_type, struct_type, typedef_type, union_type, ) point_type = struct_type('point', 8, ( (int_type('int', 4, True), 'x', 0), (int_type('int', 4, True), 'y', 32), )) line_segment_type = struct_type('line_segment', 16, ( (point_type, 'a'), (point_type, 'b', 64), )) option_type = union_type('option', 4, ( (int_type('int', 4, True), 'i'), (float_type('float', 4), 'f'), )) color_type = enum_type('color', int_type('unsigned int', 4, False), (('RED', 0), ('GREEN', 1), ('BLUE', 2))) pid_type = typedef_type('pid_t', int_type('int', 4, True)) MOCK_32BIT_PLATFORM = Platform(Architecture.UNKNOWN, PlatformFlags.IS_LITTLE_ENDIAN)