From 5c91cc6321b9ee5cb07867bef7a69853cba3d48c Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Wed, 22 May 2013 09:41:28 +0000 Subject: [PATCH] [0.3.x] added typeInfo and typedVar classes git-svn-id: https://pykd.svn.codeplex.com/svn@83754 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgexcept.cpp | 9 +-- pykd/memaccess.h | 63 ++++++++++++++++++ pykd/module.h | 2 +- pykd/pykd.vcxproj | 2 + pykd/pykd.vcxproj.filters | 6 ++ pykd/pymod.cpp | 132 +++++++++++++++++++------------------- pykd/stladaptor.h | 26 ++++++++ pykd/typedvar.h | 33 ++++++++++ pykd/typeinfo.h | 29 +++++++++ test/scripts/pykdtest.py | 8 +-- 10 files changed, 231 insertions(+), 79 deletions(-) create mode 100644 pykd/memaccess.h create mode 100644 pykd/stladaptor.h create mode 100644 pykd/typedvar.h create mode 100644 pykd/typeinfo.h diff --git a/pykd/dbgexcept.cpp b/pykd/dbgexcept.cpp index 96acd83..2358e90 100644 --- a/pykd/dbgexcept.cpp +++ b/pykd/dbgexcept.cpp @@ -11,13 +11,8 @@ namespace pykd { python::handle<> exceptPyType::pyExceptType; python::handle<> exceptPyType::pyExceptType; python::handle<> exceptPyType::pyExceptType; -//python::handle<> exceptPyType::pyExceptType; -//python::handle<> exceptPyType::pyExceptType; -////python::handle<> exceptPyType::pyExceptType; -//python::handle<> exceptPyType::pyExceptType; -//python::handle<> exceptPyType::pyExceptType; -//python::handle<> exceptPyType::pyExceptType; -//python::handle<> exceptPyType::pyExceptType; +python::handle<> exceptPyType::pyExceptType; +python::handle<> exceptPyType::pyExceptType; /////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/memaccess.h b/pykd/memaccess.h new file mode 100644 index 0000000..dd258eb --- /dev/null +++ b/pykd/memaccess.h @@ -0,0 +1,63 @@ +#pragma once + +#include +namespace python = boost::python; + +#include "kdlib/memaccess.h" + +#include "stladaptor.h" + +namespace pykd { + +inline python::list loadBytes( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +{ + return vectorToList( kdlib::loadBytes( offset, count, phyAddr ) ); +} + +inline python::list loadWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +{ + return vectorToList( kdlib::loadWords( offset, count, phyAddr ) ); +} + +inline python::list loadDWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +{ + return vectorToList( kdlib::loadDWords( offset, count, phyAddr ) ); +} + +inline python::list loadQWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +{ + return vectorToList( kdlib::loadQWords( offset, count, phyAddr ) ); +} + +inline python::list loadSignBytes( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +{ + return vectorToList( kdlib::loadSignBytes( offset, count, phyAddr ) ); +} + +inline python::list loadSignWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +{ + return vectorToList( kdlib::loadSignWords( offset, count, phyAddr ) ); +} + +inline python::list loadSignDWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +{ + return vectorToList( kdlib::loadSignDWords( offset, count, phyAddr ) ); +} + +inline python::list loadSignQWords( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +{ + return vectorToList( kdlib::loadSignQWords( offset, count, phyAddr ) ); +} + +inline python::list loadFloats( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +{ + return vectorToList( kdlib::loadFloats( offset, count, phyAddr ) ); +} + +inline python::list loadDoubles( kdlib::MEMOFFSET_64 offset, unsigned long count, bool phyAddr = false ) +{ + return vectorToList( kdlib::loadDoubles( offset, count, phyAddr ) ); +} + +} // end namespace pykd + diff --git a/pykd/module.h b/pykd/module.h index 6d900bc..f86ec5d 100644 --- a/pykd/module.h +++ b/pykd/module.h @@ -5,7 +5,7 @@ namespace pykd { -struct ModuleAdaptor : public kdlib::Module +struct ModuleAdapter : public kdlib::Module { static kdlib::ModulePtr loadModuleByName( const std::wstring &name ) diff --git a/pykd/pykd.vcxproj b/pykd/pykd.vcxproj index deaab4f..6e1c75a 100644 --- a/pykd/pykd.vcxproj +++ b/pykd/pykd.vcxproj @@ -130,6 +130,8 @@ + + diff --git a/pykd/pykd.vcxproj.filters b/pykd/pykd.vcxproj.filters index 5d70400..62822e7 100644 --- a/pykd/pykd.vcxproj.filters +++ b/pykd/pykd.vcxproj.filters @@ -42,6 +42,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 6f92403..0d24ff5 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -9,6 +9,8 @@ #include "target.h" #include "dbgexcept.h" #include "memaccess.h" +#include "typeinfo.h" +#include "typedvar.h" using namespace pykd; @@ -369,8 +371,8 @@ python::class_( "numVariant", "numVarian //python::implicitly_convertible(); python::class_, boost::noncopyable>("module", "Class representing executable module", python::no_init ) - .def("__init__", python::make_constructor(&ModuleAdaptor::loadModuleByName ) ) - .def("__init__", python::make_constructor(&ModuleAdaptor::loadModuleByOffset) ) + .def("__init__", python::make_constructor(&ModuleAdapter::loadModuleByName ) ) + .def("__init__", python::make_constructor(&ModuleAdapter::loadModuleByOffset) ) .def("begin", &kdlib::Module::getBase, "Return start address of the module" ) .def("end", &kdlib::Module::getEnd, @@ -430,67 +432,68 @@ python::class_( "numVariant", "numVarian // "Return tuple of the module's file version" ) .def("__getattr__", &kdlib::Module::getSymbolVa, "Return address of the symbol" ) - .def( "__str__", &ModuleAdaptor::print ); + .def( "__str__", &ModuleAdapter::print ); + python::class_, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init ) + .def("__init__", python::make_constructor( TypeInfoAdapter::getTypeInfoByName ) ) + .def( "name", &kdlib::TypeInfo::getName, + "Return type name" ) + .def( "size", &kdlib::TypeInfo::getSize, + "Return type size" ) + .def( "staticOffset", TypeInfoAdapter::getStaticOffset, + "Return offset of the static field" ) + .def( "fieldOffset", TypeInfoAdapter::getElementOffset, + "Return offset of the nonstatic field" ) + .def( "bitOffset", &kdlib::TypeInfo::getBitOffset, + "Return bit field's offset" ) + .def( "bitWidth", &kdlib::TypeInfo::getBitWidth, + "Return bit field's length" ) + .def( "field", TypeInfoAdapter::getElement, + "Return field's type" ) + //.def( "asMap", &kdlib::TypeInfo::asMap, + // "Return type as python dict ( for enum types )" ) + //.def( "deref", &kdlib::TypeInfo::deref, + // "Return type of pointer" ) + //.def( "append", &kdlib::TypeInfo::appendField, + // "Add a new field to custom defined struct" ) + //.def( "ptrTo", &kdlib::TypeInfo::ptrTo, + // "Return pointer to the type" ) + //.def( "arrayOf", &kdlib::TypeInfo::arrayOf, + // "Return array of the type" ) + //.def( "__str__", &TypeInfo::print, + // "Return typa as a printable string" ) + //.def( "__getattr__", &TypeInfo::getField ) + //.def("__len__", &TypeInfo::getElementCount ) + //.def("__getitem__", &TypeInfo::getElementByIndex ) + ; - // python::class_, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init ) - // .def("__init__", python::make_constructor(TypeInfo::getTypeInfoByName ) ) - // .def( "name", &TypeInfo::getName, - // "Return type name" ) - // .def( "size", &TypeInfo::getSize, - // "Return type size" ) - // .def( "staticOffset", &TypeInfo::getStaticOffsetByName, - // "Return offset of the static field" ) - // .def( "fieldOffset", &TypeInfo::getFieldOffsetByNameRecursive, - // "Return offset of the nonstatic field" ) - // .def( "bitOffset", &TypeInfo::getBitOffset, - // "Return bit field's offset" ) - // .def( "bitWidth", &TypeInfo::getBitWidth, - // "Return bit field's length" ) - // .def( "field", &TypeInfo::getField, - // "Return field's type" ) - // .def( "asMap", &TypeInfo::asMap, - // "Return type as python dict ( for enum types )" ) - // .def( "deref", &TypeInfo::deref, - // "Return type of pointer" ) - // .def( "append", &TypeInfo::appendField, - // "Add a new field to custom defined struct" ) - // .def( "ptrTo", &TypeInfo::ptrTo, - // "Return pointer to the type" ) - // .def( "arrayOf", &TypeInfo::arrayOf, - // "Return array of the type" ) - // .def( "__str__", &TypeInfo::print, - // "Return typa as a printable string" ) - // .def( "__getattr__", &TypeInfo::getField ) - // .def("__len__", &TypeInfo::getElementCount ) - // .def("__getitem__", &TypeInfo::getElementByIndex ); - - // python::class_, boost::noncopyable >("typedVar", - // "Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance", python::no_init ) - // .def("__init__", python::make_constructor(TypedVar::getTypedVarByName) ) - // .def("__init__", python::make_constructor(TypedVar::getTypedVarByTypeName) ) - // .def("__init__", python::make_constructor(TypedVar::getTypedVarByTypeInfo) ) - // .def("getAddress", &TypedVar::getAddress, - // "Return virtual address" ) - // .def("sizeof", &TypedVar::getSize, - // "Return size of a variable in the target memory" ) - // .def("fieldOffset", &TypedVar::getFieldOffsetByNameRecursive, - // "Return target field offset" ) - // .def("field", &TypedVar::getField, - // "Return field of structure as an object attribute" ) - // .def( "dataKind", &TypedVar::getDataKind, - // "Retrieves the variable classification of a data: DataIsXxx") - // .def("deref", &TypedVar::deref, - // "Return value by pointer" ) - // .def("type", &TypedVar::getType, - // "Return typeInfo instance" ) - // .def("__getattr__", &TypedVar::getField, - // "Return field of structure as an object attribute" ) - // .def( "__str__", &TypedVar::print ) - // .def("__len__", &TypedVar::getElementCount ) - // .def("__getitem__", &TypedVar::getElementByIndex ) - // .def("__getitem__", &TypedVar::getElementByIndexPtr ); + python::class_, boost::noncopyable >("typedVar", + "Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance", python::no_init ) + .def("__init__", python::make_constructor(TypedVarAdapter::getTypedVarByName) ) + .def("__init__", python::make_constructor(TypedVarAdapter::getTypedVarByTypeName) ) + .def("__init__", python::make_constructor(TypedVarAdapter::getTypedVarByTypeInfo) ) + .def("getAddress", &kdlib::TypedVar::getAddress, + "Return virtual address" ) + .def("sizeof", &kdlib::TypedVar::getSize, + "Return size of a variable in the target memory" ) + .def("fieldOffset", TypedVarAdapter::getFieldOffsetByName, + "Return target field offset" ) + .def("field", TypedVarAdapter::getField, + "Return field of structure as an object attribute" ) + //.def( "dataKind", &kdlib::TypedVar::getDataKind, + // "Retrieves the variable classification of a data: DataIsXxx") + /* .def("deref", &kdlib::TypedVar::deref, + "Return value by pointer" ) + .def("type", &kdlib::TypedVar::getType, + "Return typeInfo instance" )*/ + .def("__getattr__", TypedVarAdapter::getField, + "Return field of structure as an object attribute" ) + //.def( "__str__", &kdlib::TypedVar::print ) + .def("__len__", &kdlib::TypedVar::getElementCount ) + //.def("__getitem__", &kdlib::TypedVar::getElementByIndex ) + //.def("__getitem__", &kdlib::TypedVar::getElementByIndexPtr ) + ; // python::class_("typeBuilder", // "Class for building dynamically defined types", boost::python::no_init ) @@ -667,13 +670,8 @@ python::class_( "numVariant", "numVarian pykd::exception( "DbgException", "Pykd base exception class" ); pykd::exception( "MemoryException", "Target memory access exception class" ); - // pykd::exception( "WaitEventException", "None of the targets could generate events" ); - // pykd::exception( "WrongEventTypeException", "Unknown last event type" ); - // pykd::exception( "SymbolException", "Symbol exception" ); - // //pykd::exception( "DiaException", "Debug interface access exception" ); - // pykd::exception( "TypeException", "type exception" ); - // //pykd::exception( "AddSynSymbolException", "synthetic symbol exception" ); - // //pykd::exception( "ImplementException", "implementation exception" ); + pykd::exception( "SymbolException", "Symbol exception" ); + pykd::exception( "TypeException", "type exception" ); } ////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/pykd/stladaptor.h b/pykd/stladaptor.h new file mode 100644 index 0000000..b1b2158 --- /dev/null +++ b/pykd/stladaptor.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include +namespace python = boost::python; + +namespace pykd { + +template +python::list vectorToList( const std::vector &v ) { + python::list lst; + for ( std::vector::const_iterator it = v.begin(); it != v.end(); ++it ) + lst.append( *it ); + return lst; +} + +template<> +python::list vectorToList( const std::vector &v ) { + python::list lst; + for ( std::vector::const_iterator it = v.begin(); it != v.end(); ++it ) + lst.append( int(*it) ); + return lst; +} + +} // end namespace pykd diff --git a/pykd/typedvar.h b/pykd/typedvar.h new file mode 100644 index 0000000..fb61962 --- /dev/null +++ b/pykd/typedvar.h @@ -0,0 +1,33 @@ +#pragma once + +#include "kdlib/typedvar.h" + +namespace pykd { + +struct TypedVarAdapter { + + static kdlib::TypedVarPtr getTypedVarByName( const std::wstring &name ) { + return kdlib::loadTypedVar( name ); + } + + static kdlib::TypedVarPtr getTypedVarByTypeName( const std::wstring &name, kdlib::MEMOFFSET_64 addr ) { + return kdlib::loadTypedVar( name, addr ); + } + + static kdlib::TypedVarPtr getTypedVarByTypeInfo( const kdlib::TypeInfoPtr &typeInfo, kdlib::MEMOFFSET_64 addr ) + { + return kdlib::loadTypedVar( typeInfo, addr ); + } + + static kdlib::MEMOFFSET_32 getFieldOffsetByName( kdlib::TypedVar& typedVar, const std::wstring &name ) { + return typedVar.getElementOffset( name ); + } + + static kdlib::TypedVarPtr getField( kdlib::TypedVar& typedVar, const std::wstring &name ) { + return typedVar.getElement( name ); + } + + +}; + +} // end namespace pykd diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h new file mode 100644 index 0000000..75cd0a7 --- /dev/null +++ b/pykd/typeinfo.h @@ -0,0 +1,29 @@ +#pragma once + +#include "kdlib/typeinfo.h" + +namespace pykd { + +struct TypeInfoAdapter : public kdlib::TypeInfo { + + static kdlib::TypeInfoPtr getTypeInfoByName( const std::wstring &name ) + { + return kdlib::loadType( name ); + } + + static kdlib::MEMOFFSET_32 getElementOffset( kdlib::TypeInfo &typeInfo, const std::wstring &name ) { + return typeInfo.getElementOffset( name ); + } + + + static kdlib::MEMOFFSET_64 getStaticOffset( kdlib::TypeInfo &typeInfo, const std::wstring &name ) { + return typeInfo.getElementVa( name ); + } + + + static kdlib::TypeInfoPtr getElement( kdlib::TypeInfo &typeInfo, const std::wstring &name ) { + return typeInfo.getElement(name); + } +}; + +} // end namespace pykd diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index 5fd6da4..b307aa8 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -16,8 +16,8 @@ import target import intbase import memtest import moduletest -#import typeinfo -#import typedvar +import typeinfo +import typedvar #import regtest #import mspdbtest #import localstest @@ -49,8 +49,8 @@ def getTestSuite( singleName = "" ): # *** Test without start/kill new processes unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ), unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ), - #unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), - #unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ), + unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ), + unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ), #unittest.TestLoader().loadTestsFromTestCase( regtest.CpuRegTest ), #unittest.TestLoader().loadTestsFromTestCase( customtypestest.CustomTypesTest ), # ^^^