diff --git a/libdrgn/python/program.c b/libdrgn/python/program.c index ec7e8d48..16dc1b40 100644 --- a/libdrgn/python/program.c +++ b/libdrgn/python/program.c @@ -579,50 +579,6 @@ static PyObject *Program_pointer_type(Program *self, PyObject *args, return DrgnType_wrap(qualified_type, (PyObject *)self); } -static Symbol *Program_symbol(Program *self, PyObject *args, PyObject *kwds) -{ - static char *keywords[] = {"name", "flags", "filename", NULL}; - struct drgn_error *err; - const char *name; - struct enum_arg flags = {.type = FindObjectFlags_class}; - struct path_arg filename = {.allow_none = true}; - Symbol *sym_obj; - bool clear; - struct drgn_qualified_type qualified_type; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO&|O&:_symbol", keywords, - &name, enum_converter, &flags, - path_converter, &filename)) - return NULL; - - sym_obj = (Symbol *)Symbol_type.tp_alloc(&Symbol_type, 0); - if (!sym_obj) { - path_cleanup(&filename); - return NULL; - } - - clear = set_drgn_in_python(); - err = drgn_symbol_index_find(&self->prog.sindex, name, filename.path, - flags.value, &sym_obj->sym); - if (clear) - clear_drgn_in_python(); - path_cleanup(&filename); - if (err) { - Py_DECREF(sym_obj); - return set_drgn_error(err); - } - - qualified_type.type = sym_obj->sym.type; - qualified_type.qualifiers = sym_obj->sym.qualifiers; - sym_obj->type_obj = (DrgnType *)DrgnType_wrap(qualified_type, - (PyObject *)self); - if (!sym_obj->type_obj) { - Py_DECREF(sym_obj); - return NULL; - } - return sym_obj; -} - static DrgnObject *Program_find_object(Program *self, const char *name, struct path_arg *filename, enum drgn_find_object_flags flags) @@ -821,8 +777,6 @@ static PyMethodDef Program_methods[] = { drgn_Program_type_DOC}, {"pointer_type", (PyCFunction)Program_pointer_type, METH_VARARGS | METH_KEYWORDS, drgn_Program_pointer_type_DOC}, - {"_symbol", (PyCFunction)Program_symbol, METH_VARARGS | METH_KEYWORDS, - "Like object(), but returns a Symbol for testing."}, {"object", (PyCFunction)Program_object, METH_VARARGS | METH_KEYWORDS, drgn_Program_object_DOC}, {"constant", (PyCFunction)Program_constant, diff --git a/tests/test_dwarf.py b/tests/test_dwarf.py index 9a0a6c51..edb142a5 100644 --- a/tests/test_dwarf.py +++ b/tests/test_dwarf.py @@ -5,9 +5,9 @@ import unittest from drgn import ( FileFormatError, FindObjectFlags, + Object, Program, Qualifiers, - Symbol, array_type, complex_type, enum_type, @@ -20,12 +20,7 @@ from drgn import ( union_type, void_type, ) -from tests import ( - color_type, - option_type, - pid_type, - point_type, -) +from tests import ObjectTestCase, color_type, option_type, pid_type, point_type from tests.dwarf import DW_AT, DW_ATE, DW_FORM, DW_TAG from tests.dwarfwriter import compile_dwarf, DwarfDie, DwarfAttrib @@ -1570,7 +1565,7 @@ class TestTypes(unittest.TestCase): False)) -class TestSymbols(unittest.TestCase): +class TestObjects(ObjectTestCase): def test_constant(self): dies = [ int_die, @@ -1619,22 +1614,20 @@ class TestSymbols(unittest.TestCase): type_ = enum_type('color', int_type('int', 4, True), [('RED', 0), ('GREEN', 1), ('BLUE', 2)]) prog = dwarf_program(dies) - self.assertEqual(prog._symbol('BLUE', FindObjectFlags.ANY), - Symbol(type=type_, value=2)) + self.assertEqual(prog['BLUE'], Object(prog, type_, value=2)) dies[0] = unsigned_int_die type_ = enum_type('color', int_type('unsigned int', 4, False), [('RED', 0), ('GREEN', 1), ('BLUE', 2)]) prog = dwarf_program(dies) - self.assertEqual(prog._symbol('GREEN', FindObjectFlags.ANY), - Symbol(type=type_, value=1)) + self.assertEqual(prog['GREEN'], Object(prog, type_, value=1)) del dies[1].attribs[0] type_ = enum_type(None, int_type('unsigned int', 4, False), [('RED', 0), ('GREEN', 1), ('BLUE', 2)]) prog = dwarf_program(dies) - self.assertEqual(prog._symbol('RED', flags=FindObjectFlags.CONSTANT), - Symbol(type=type_, value=0)) + self.assertEqual(prog.object('RED', FindObjectFlags.CONSTANT), + Object(prog, type_, value=0)) def test_function(self): dies = [ @@ -1658,19 +1651,17 @@ class TestSymbols(unittest.TestCase): ((int_type('int', 1, True),),), False) prog = dwarf_program(dies) - self.assertEqual(prog._symbol('abs', FindObjectFlags.ANY), - Symbol(type=type_, address=0x7fc3eb9b1c30, - byteorder='little')) - self.assertEqual(prog._symbol('abs', flags=FindObjectFlags.FUNCTION), - prog._symbol('abs', flags=FindObjectFlags.ANY)) + self.assertEqual(prog['abs'], + Object(prog, type_, address=0x7fc3eb9b1c30)) + self.assertEqual(prog.object('abs', FindObjectFlags.FUNCTION), + prog['abs']) self.assertRaisesRegex(LookupError, 'could not find variable', - prog._symbol, 'abs', - flags=FindObjectFlags.VARIABLE) + prog.object, 'abs', FindObjectFlags.VARIABLE) del dies[1].attribs[2] prog = dwarf_program(dies) self.assertRaisesRegex(LookupError, 'could not find address', - prog._symbol, 'abs', FindObjectFlags.ANY) + prog.object, 'abs') def test_variable(self): dies = [ @@ -1687,28 +1678,25 @@ class TestSymbols(unittest.TestCase): ] prog = dwarf_program(dies) - self.assertEqual(prog._symbol('x', FindObjectFlags.ANY), - Symbol(type=int_type('int', 4, True), - address=0xffffffff01020304, - byteorder='little')) - self.assertEqual(prog._symbol('x', flags=FindObjectFlags.VARIABLE), - prog._symbol('x', FindObjectFlags.ANY)) + self.assertEqual(prog['x'], + Object(prog, int_type('int', 4, True), + address=0xffffffff01020304)) + self.assertEqual(prog.object('x', FindObjectFlags.VARIABLE), + prog['x']) self.assertRaisesRegex(LookupError, 'could not find constant', - prog._symbol, 'x', - flags=FindObjectFlags.CONSTANT) + prog.object, 'x', FindObjectFlags.CONSTANT) del dies[1].attribs[2] prog = dwarf_program(dies) self.assertRaisesRegex(LookupError, 'could not find address', - prog._symbol, 'x', FindObjectFlags.ANY) + prog.object, 'x') dies[1].attribs.insert( 2, DwarfAttrib(DW_AT.location, DW_FORM.exprloc, b'\xe0')) prog = dwarf_program(dies) self.assertRaisesRegex(FileFormatError, 'unimplemented operation', - prog._symbol, 'x', FindObjectFlags.ANY) + prog.object, 'x') def test_not_found(self): prog = dwarf_program([int_die]) - self.assertRaisesRegex(LookupError, 'could not find', prog._symbol, - 'y', FindObjectFlags.ANY) + self.assertRaisesRegex(LookupError, 'could not find', prog.object, 'y') diff --git a/tests/test_program.py b/tests/test_program.py index d800298d..baed0e48 100644 --- a/tests/test_program.py +++ b/tests/test_program.py @@ -9,6 +9,7 @@ from drgn import ( Architecture, FaultError, FindObjectFlags, + Object, Program, ProgramFlags, Qualifiers, @@ -26,6 +27,7 @@ from tests import ( MOCK_32BIT_ARCH, MOCK_ARCH, MockMemorySegment, + ObjectTestCase, color_type, mock_program, option_type, @@ -469,52 +471,52 @@ class TestTypes(unittest.TestCase): array_type(2, pointer_type(8, array_type(3, int_type('int', 4, True))))) -class TestSymbols(unittest.TestCase): +class TestObjects(ObjectTestCase): def test_invalid_finder(self): self.assertRaises(TypeError, mock_program().add_symbol_finder, 'foo') prog = mock_program() prog.add_symbol_finder(lambda name, flags, filename: 'foo') - self.assertRaises(TypeError, prog._symbol, 'foo', FindObjectFlags.ANY) + self.assertRaises(TypeError, prog.object, 'foo') def test_not_found(self): prog = mock_program() - self.assertRaises(LookupError, prog._symbol, 'foo', FindObjectFlags.ANY) + self.assertRaises(LookupError, prog.object, 'foo') prog.add_symbol_finder(lambda name, flags, filename: None) - self.assertRaises(LookupError, prog._symbol, 'foo', FindObjectFlags.ANY) + self.assertRaises(LookupError, prog.object, 'foo') self.assertFalse('foo' in prog) def test_constant(self): sym = Symbol(int_type('int', 4, True), value=4096) prog = mock_program(symbols=[('PAGE_SIZE', sym)]) - self.assertEqual(prog._symbol('PAGE_SIZE', FindObjectFlags.CONSTANT), - sym) - self.assertEqual(prog._symbol('PAGE_SIZE', FindObjectFlags.ANY), sym) + self.assertEqual(prog['PAGE_SIZE'], + Object(prog, int_type('int', 4, True), value=4096)) + self.assertEqual(prog.object('PAGE_SIZE', FindObjectFlags.CONSTANT), + prog['PAGE_SIZE']) self.assertTrue('PAGE_SIZE' in prog) def test_function(self): sym = Symbol(function_type(void_type(), (), False), address=0xffff0000, byteorder='little') prog = mock_program(symbols=[('func', sym)]) - self.assertEqual(prog._symbol('func', FindObjectFlags.FUNCTION), sym) - self.assertEqual(prog._symbol('func', FindObjectFlags.ANY), sym) + 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_variable(self): sym = Symbol(int_type('int', 4, True), address=0xffff0000, byteorder='little') prog = mock_program(symbols=[('counter', sym)]) - self.assertEqual(prog._symbol('counter', FindObjectFlags.VARIABLE), sym) - self.assertEqual(prog._symbol('counter', FindObjectFlags.ANY), sym) + self.assertEqual(prog['counter'], + Object(prog, int_type('int', 4, True), + address=0xffff0000)) + self.assertEqual(prog.object('counter', FindObjectFlags.VARIABLE), + prog['counter']) self.assertTrue('counter' in prog) - def test_wrong_kind(self): - prog = mock_program() - prog.add_symbol_finder(lambda name, flags, filename: - Symbol(color_type, is_enumerator=True)) - self.assertRaisesRegex(TypeError, 'wrong kind', prog._symbol, 'foo', - FindObjectFlags.VARIABLE | FindObjectFlags.FUNCTION) - class TestCoreDump(unittest.TestCase): def test_not_core_dump(self):