From 5879200d075ba5354b49d41a460b306cbdc0c973 Mon Sep 17 00:00:00 2001 From: "SND\\EreTIk_cp" Date: Fri, 18 Feb 2011 20:56:26 +0000 Subject: [PATCH] [+] part of functional (work with types) moved from typedVarClass into base class: typeClass [-] remove field m_size, which is duplicated in TypeInfo m_typeInfo [+] added function getTypeClass() - create instance of typeClass by module an type name git-svn-id: https://pykd.svn.codeplex.com/svn@61649 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgext.cpp | 10 +-- pykd/dbgtype.cpp | 179 ++++++++++++++++++++++++++++------------------- pykd/dbgtype.h | 101 ++++++++++++++++++-------- 3 files changed, 185 insertions(+), 105 deletions(-) diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index e4b49e0..14cf40e 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -107,6 +107,7 @@ BOOST_PYTHON_MODULE( pykd ) boost::python::def( "typedVarList", &loadTypedVarList ); boost::python::def( "typedVarArray", &loadTypedVarArray ); boost::python::def( "containingRecord", &containingRecord ); + boost::python::def( "getTypeClass", &getTypeClass ); boost::python::def( "sizeof", &sizeofType ); boost::python::def( "loadModule", &loadModule ); boost::python::def( "findSymbol", &findSymbolForAddress ); @@ -150,10 +151,11 @@ BOOST_PYTHON_MODULE( pykd ) boost::python::def( "setCurrentProcess", &setCurrentProcess ); boost::python::def( "getProcessorMode", &getProcessorMode ); boost::python::def( "setProcessorMode", &setProcessorMode ); - boost::python::class_ >( "typedVarClass" ) - .def("getAddress", &typedVarClass::getAddress ) - .def("sizeof", &typedVarClass::size ) - .def("__str__", &typedVarClass::print); + boost::python::class_ >( "typeClass" ) + .def("sizeof", &typeClass::size ) + .def("__str__", &typeClass::print); + boost::python::class_, boost::shared_ptr >( "typedVarClass" ) + .def("getAddress", &typedVarClass::getAddress ); boost::python::class_( "dbgModuleClass" ) .def("begin", &dbgModuleClass::getBegin ) .def("end", &dbgModuleClass::getEnd ) diff --git a/pykd/dbgtype.cpp b/pykd/dbgtype.cpp index 5a93ea9..536a6d5 100644 --- a/pykd/dbgtype.cpp +++ b/pykd/dbgtype.cpp @@ -91,6 +91,32 @@ containingRecord( ULONG64 address, const std::string &moduleName, const std::str ///////////////////////////////////////////////////////////////////////////////// +boost::python::object +getTypeClass( const std::string &moduleName, const std::string &typeName ) +{ + try + { + boost::shared_ptr ptr( + new typeClass( TypeInfo::get( moduleName, typeName )) + ); + boost::python::object var( ptr ); + ptr->setPyObj(var); + + return var; + } + catch( std::exception &e ) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); + } + catch(...) + { + dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); + } + return boost::python::object(); +} + +///////////////////////////////////////////////////////////////////////////////// + boost::python::object loadTypedVarList( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &listEntryName ) { @@ -330,10 +356,10 @@ TypeInfo::load( ULONG64 addr ) const if ( m_baseType ) return loadBaseType( addr ); - boost::shared_ptr ptr( new typedVarClass( *this, addr, m_size ) ); + boost::shared_ptr ptr( new typedVarClass( *this, addr ) ); boost::python::object var( ptr ); ptr->setPyObj( var ); - + TypeFieldList::const_iterator field = m_fields.begin(); for ( field = m_fields.begin(); field != m_fields.end(); ++field ) { @@ -436,81 +462,92 @@ valueLoader( ULONG64 address, ULONG size ) ///////////////////////////////////////////////////////////////////////////////// -std::string -typedVarClass::print() const +std::string typeClass::print() const { - stringstream sstr; - - for ( - TypeInfo::TypeFieldList::const_iterator field = m_typeInfo.getFields().begin(); - field != m_typeInfo.getFields().end(); - field++ ) + stringstream sstr; + + sstr << getTypeInfo().name() << std::endl; + + TypeInfo::TypeFieldList::const_iterator itField = + getTypeInfo().getFields().begin(); + while (itField != getTypeInfo().getFields().end()) { - sstr << "\t" << hex << "+" << field->offset << " " << field->name << " "; - - if ( field->type.isComplex() && !field->type.isPtr()) - sstr << field->type.name(); - else - { - boost::python::object attr = m_pyobj.attr( field->name.c_str() ); - - if ( field->size == field->type.size() ) - { - if ( attr.ptr() == Py_None ) - { - sstr << "memory error"; - } - else - { - unsigned __int64 val = boost::python::extract( attr ); - - sstr << hex << "0x" << val; - - if ( field->type.name() == "char*" ) - { - char buf[0x100]; - if ( loadCStrToBuffer( val, buf, sizeof(buf) ) ) - sstr << " (" << buf << " )"; - else - sstr << " ( read string error )"; - } - else if ( field->type.name() == "unsigned short*" ) - { - wchar_t wbuf[0x100]; - if ( loadWStrToBuffer( val, wbuf, sizeof(wbuf) ) ) - { - char mbBuf[0x100] = { 0 }; - - WideCharToMultiByte( CP_ACP, 0, wbuf, wcslen(wbuf)+1, mbBuf, sizeof(mbBuf), NULL, NULL ); - - sstr << " (" << mbBuf << " )"; - } - else - sstr << " ( read string error )"; - } - else - { - sstr << dec << " ( " << val << " )"; - } - } - } - else - { - for ( size_t i = 0; i < field->size/field->type.size(); ++i ) - { - unsigned __int64 val = boost::python::extract( attr[i] ); - - sstr << "\n\t\t\t[" << i << "] " << hex << "0x" << val << dec << " ( " << val << " )"; - } - } - } - + sstr << "\t" << hex << "+" << itField->offset; + sstr << " " << itField->name << " "; + + printField(*itField, sstr); + sstr << std::endl; - } - + + ++itField; + } + return sstr.str(); } ///////////////////////////////////////////////////////////////////////////////// +void +typedVarClass::printField(const TypeInfo::TypeField &field, stringstream &sstr) const +{ + if ( field.type.isComplex() && !field.type.isPtr()) + sstr << field.type.name(); + else + { + boost::python::object attr = getPyObj().attr( field.name.c_str() ); + + if ( field.size == field.type.size() ) + { + if ( attr.ptr() == Py_None ) + { + sstr << "memory error"; + } + else + { + unsigned __int64 val = boost::python::extract( attr ); + + sstr << hex << "0x" << val; + + if ( field.type.name() == "char*" ) + { + char buf[0x100]; + if ( loadCStrToBuffer( val, buf, sizeof(buf) ) ) + sstr << " (" << buf << " )"; + else + sstr << " ( read string error )"; + } + else if ( field.type.name() == "unsigned short*" ) + { + wchar_t wbuf[0x100]; + if ( loadWStrToBuffer( val, wbuf, sizeof(wbuf) ) ) + { + char mbBuf[0x100] = { 0 }; + + WideCharToMultiByte( CP_ACP, 0, wbuf, wcslen(wbuf)+1, mbBuf, sizeof(mbBuf), NULL, NULL ); + + sstr << " (" << mbBuf << " )"; + } + else + sstr << " ( read string error )"; + } + else + { + sstr << dec << " ( " << val << " )"; + } + } + } + else + { + for ( size_t i = 0; i < field.size/field.type.size(); ++i ) + { + unsigned __int64 val = boost::python::extract( attr[i] ); + + sstr << "\n\t\t\t[" << i << "] " << hex << "0x" << val << dec << " ( " << val << " )"; + } + } + } +} + +///////////////////////////////////////////////////////////////////////////////// + diff --git a/pykd/dbgtype.h b/pykd/dbgtype.h index 1bb1955..1b5147d 100644 --- a/pykd/dbgtype.h +++ b/pykd/dbgtype.h @@ -23,6 +23,9 @@ loadTypedVarArray( ULONG64 address, const std::string &moduleName, const std::st boost::python::object containingRecord( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &fieldName ); +boost::python::object +getTypeClass( const std::string &moduleName, const std::string &typeName ); + ULONG sizeofType( const std::string &moduleName, const std::string &typeName ); @@ -138,58 +141,96 @@ private: private: bool m_baseType; - bool m_pointer; - TypeFieldList m_fields; - std::string m_typeName; - ULONG m_size; }; ///////////////////////////////////////////////////////////////////////////////// -class typedVarClass { +class typeClass +{ +public: + + typeClass() + { + } + + typeClass( + const TypeInfo &typeInfo + ) : m_typeInfo(typeInfo) + { + } + + ULONG size() const + { + return m_typeInfo.size(); + } + + void setPyObj( const boost::python::object &obj ) + { + m_pyobj = obj; + } + + TypeInfo &getTypeInfo() + { + return m_typeInfo; + } + const TypeInfo &getTypeInfo() const + { + return m_typeInfo; + } + + boost::python::object &getPyObj() + { + return m_pyobj; + } + const boost::python::object &getPyObj() const + { + return m_pyobj; + } + + std::string print() const; + + virtual void printField( + const TypeInfo::TypeField &field, + std::stringstream &sstr + ) const + { + // no data - nothing print + } + +private: + TypeInfo m_typeInfo; + boost::python::object m_pyobj; +}; + +///////////////////////////////////////////////////////////////////////////////// + +class typedVarClass : public typeClass { public: typedVarClass() {} - typedVarClass( const TypeInfo &typeInfo, ULONG64 addr, ULONG size ) : - m_typeInfo( typeInfo ), - m_addr( addr ), - m_size( size ) + typedVarClass( const TypeInfo &typeInfo, ULONG64 addr) : + typeClass( typeInfo ), + m_addr( addr ) {} - + ULONG64 getAddress() const { return m_addr; } - - ULONG - size() const { - return m_size; - } - - std::string - print() const; - - void - setPyObj( const boost::python::object &obj ) { - m_pyobj = obj; - } - + + virtual void + printField(const TypeInfo::TypeField &field, std::stringstream &sstr) const override; + private: ULONG64 m_addr; - - ULONG m_size; - - TypeInfo m_typeInfo; - - boost::python::object m_pyobj; }; ///////////////////////////////////////////////////////////////////////////////// \ No newline at end of file