From c498137a512dde73c156eb48ca8a5860f6fd24cd Mon Sep 17 00:00:00 2001 From: ussrhero Date: Wed, 3 Oct 2018 20:43:02 +0300 Subject: [PATCH] added : baseClassOffset ( retrun offset of base class ) added : baseClasses ( return list of tuples ( baseClassName, baseClassOffset, baseClassType ) ) --- pykd/pymod.cpp | 6 ++++++ pykd/pytypeinfo.cpp | 29 +++++++++++++++++++++++++++++ pykd/pytypeinfo.h | 14 ++++++++++++++ test/scripts/pykdtest.pyproj | 2 +- test/scripts/typeinfo.py | 7 +++++++ 5 files changed, 57 insertions(+), 1 deletion(-) diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index cf44987..3e830dc 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -918,6 +918,12 @@ void pykd_init() "Return a base class's type by name" ) .def( "baseClass", TypeInfoAdapter::getBaseClassByIndex, "Return a base class's type by index" ) + .def("baseClassOffset", TypeInfoAdapter::getBaseClassOffsetByName, + "Return a base class offset by name") + .def("baseClassOffset", TypeInfoAdapter::getBaseClassOffsetByIndex, + "Return a base class offset by index") + .def("baseClasses", TypeInfoAdapter::getBaseClasses, + "Return list of tuples ( baseClassName, baseClassOffset, baseClassType)") .def( "deref", TypeInfoAdapter::deref, "Return type of pointer" ) .def( "append", TypeInfoAdapter::appendField, diff --git a/pykd/pytypeinfo.cpp b/pykd/pytypeinfo.cpp index f289fb2..96bbb5a 100644 --- a/pykd/pytypeinfo.cpp +++ b/pykd/pytypeinfo.cpp @@ -131,6 +131,35 @@ python::list TypeInfoAdapter::getMethods(kdlib::TypeInfo &typeInfo) return pylst; } +python::list TypeInfoAdapter::getBaseClasses(kdlib::TypeInfo &typeInfo) +{ + typedef boost::tuple BaseClassTuple; + + std::list lst; + + do { + + AutoRestorePyState pystate; + + for (size_t i = 0; i < typeInfo.getBaseClassesCount(); ++i) + { + kdlib::TypeInfoPtr classType = typeInfo.getBaseClass(i); + std::wstring name = classType->getName(); + kdlib::MEMOFFSET_32 offset = typeInfo.getBaseClassOffset(i); + + lst.push_back(BaseClassTuple(name, offset, classType)); + } + + } while (false); + + python::list pylst; + + for (auto it = lst.begin(); it != lst.end(); ++it) + pylst.append(python::make_tuple(it->get<0>(), it->get<1>(), it->get<2>())); + + return pylst; +} + /////////////////////////////////////////////////////////////////////////////// kdlib::TypeInfoPtr TypeInfoAdapter::getElementAttr(kdlib::TypeInfo &typeInfo, const std::wstring &name) diff --git a/pykd/pytypeinfo.h b/pykd/pytypeinfo.h index 096cf22..e908f08 100644 --- a/pykd/pytypeinfo.h +++ b/pykd/pytypeinfo.h @@ -202,6 +202,18 @@ struct TypeInfoAdapter : public kdlib::TypeInfo { return typeInfo.getBaseClass(index); } + static kdlib::MEMOFFSET_32 getBaseClassOffsetByName(kdlib::TypeInfo &typeInfo, const std::wstring& className) + { + AutoRestorePyState pystate; + return typeInfo.getBaseClassOffset(className); + } + + static kdlib::MEMOFFSET_32 getBaseClassOffsetByIndex(kdlib::TypeInfo &typeInfo, size_t index) + { + AutoRestorePyState pystate; + return typeInfo.getBaseClassOffset(index); + } + static kdlib::TypeInfoPtr ptrTo( kdlib::TypeInfo &typeInfo, size_t ptrSize = 0 ) { AutoRestorePyState pystate; @@ -316,6 +328,8 @@ struct TypeInfoAdapter : public kdlib::TypeInfo { static python::list getElementDir(kdlib::TypeInfo &typeInfo); + static python::list getBaseClasses(kdlib::TypeInfo &typeInfo); + static bool isZero(kdlib::TypeInfo &typeInfo) { return false; } diff --git a/test/scripts/pykdtest.pyproj b/test/scripts/pykdtest.pyproj index 2768fab..64fbacd 100644 --- a/test/scripts/pykdtest.pyproj +++ b/test/scripts/pykdtest.pyproj @@ -17,7 +17,7 @@ - False + True False Global|PythonCore|2.7 diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index f7be3b3..34b864d 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -344,6 +344,13 @@ class TypeInfoTest( unittest.TestCase ): def testGetBaseClass(self): classChild = target.module.type("classChild") self.assertEqual( ["classBase1", "classBase2"], [ classChild.baseClass(i).name() for i in range(classChild.getNumberBaseClasses()) ] ) + self.assertEqual( ["classBase1", "classBase2"], [ name for name, _, _ in classChild.baseClasses()] ) + + def testGetBaseClassOffset(self): + classChild = target.module.type("classChild") + self.assertEqual( classChild.baseClassOffset(0), classChild.baseClassOffset('classBase1')) + self.assertEqual(classChild.baseClassOffset(1), classChild.baseClassOffset('classBase2')) + def testPdbTypeProvider(self): pdb = target.module.symfile()