From 1609c0cac6b5a34788e9be5255e5657b60d84585 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Tue, 6 Dec 2011 15:49:25 +0000 Subject: [PATCH] [0.1.x] update : create typeInfo by name for "complex" type ( mixed array and pointers ) git-svn-id: https://pykd.svn.codeplex.com/svn@72061 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/typeinfo.cpp | 96 +++++++++++++++++++++++++++++++++------- pykd/typeinfo.h | 19 ++++++-- test/scripts/typeinfo.py | 2 +- 3 files changed, 97 insertions(+), 20 deletions(-) diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp index c72644e..6f102ce 100644 --- a/pykd/typeinfo.cpp +++ b/pykd/typeinfo.cpp @@ -30,7 +30,7 @@ TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &typeSym ) ///////////////////////////////////////////////////////////////////////////////////// -static const boost::regex arrayMatch("^(.*)\\[(\\d+)\\]$"); +//static const boost::regex arrayMatch("^(.*)\\[(\\d+)\\]$"); TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName ) { @@ -50,20 +50,22 @@ TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &symScope, const std::strin return getTypeInfo( typeSym ); } - if ( symName[ symName.size() - 1 ] == '*' ) - return TypeInfoPtr( new PointerTypeInfo( symScope,symName.substr( 0, symName.size() - 1 ) ) ); + return getComplexType( symScope, symName ); - boost::cmatch matchResult; + //if ( symName[ symName.size() - 1 ] == '*' ) + // return TypeInfoPtr( new PointerTypeInfo( symScope,symName.substr( 0, symName.size() - 1 ) ) ); - if ( boost::regex_match( symName.c_str(), matchResult, arrayMatch ) ) - { - std::string sym = std::string( matchResult[1].first, matchResult[1].second ); + //boost::cmatch matchResult; - return TypeInfoPtr( new ArrayTypeInfo( symScope, sym, std::atoi( matchResult[2].first ) ) ); - } + //if ( boost::regex_match( symName.c_str(), matchResult, arrayMatch ) ) + //{ + // std::string sym = std::string( matchResult[1].first, matchResult[1].second ); + + // return TypeInfoPtr( new ArrayTypeInfo( symScope, sym, std::atoi( matchResult[2].first ) ) ); + //} - throw DbgException( "type name invalid" ); + //throw DbgException( "type name invalid" ); } ///////////////////////////////////////////////////////////////////////////////////// @@ -160,7 +162,6 @@ PointerTypeInfo::PointerTypeInfo( pyDia::SymbolPtr &symScope, const std::string std::string PointerTypeInfo::getName() { - //return m_derefType->getName() + '*'; return getComplexName(); } @@ -191,11 +192,6 @@ ArrayTypeInfo::ArrayTypeInfo( pyDia::SymbolPtr &symScope, const std::string &sym std::string ArrayTypeInfo::getName() { - //std::stringstream sstr; - - //sstr << m_derefType->getName() << '[' << m_count << ']'; - - //return sstr.str(); return getComplexName(); } @@ -260,4 +256,72 @@ std::string TypeInfo::getComplexName() ///////////////////////////////////////////////////////////////////////////////////// +static const boost::regex bracketMatch("^([^\\(]*)\\((.*)\\)([^\\)]*)$"); + +static const boost::regex typeMatch("^([^\\(\\)\\*\\[\\]]*)([\\(\\)\\*\\[\\]\\d]*)$"); + +static const boost::regex ptrMatch("^\\*(.*)$"); + +static const boost::regex arrayMatch("^(.*)\\[(\\d+)\\]$"); + +TypeInfoPtr TypeInfo::getComplexType( pyDia::SymbolPtr &symScope, const std::string &symName ) +{ + ULONG ptrSize = (symScope->getMachineType() == IMAGE_FILE_MACHINE_AMD64) ? 8 : 4; + + boost::cmatch matchResult; + + if ( !boost::regex_match( symName.c_str(), matchResult, typeMatch ) ) + DbgException( "type name invalid" ); + + TypeInfoPtr lowestTypeInfo = getTypeInfo( symScope, std::string( matchResult[1].first, matchResult[1].second ) ); + + return getRecurciveComplexType( lowestTypeInfo, std::string( matchResult[2].first, matchResult[2].second ), ptrSize ); +} + +///////////////////////////////////////////////////////////////////////////////////// + +TypeInfoPtr TypeInfo::getRecurciveComplexType( TypeInfoPtr &lowestType, std::string &suffix, ULONG ptrSize ) +{ + boost::cmatch matchResult; + + std::string bracketExpr; + + if ( boost::regex_match( suffix.c_str(), matchResult, bracketMatch ) ) + { + bracketExpr = std::string( matchResult[2].first, matchResult[2].second ); + + suffix = ""; + + if ( matchResult[1].matched ) + suffix += std::string( matchResult[1].first, matchResult[1].second ); + + if ( matchResult[3].matched ) + suffix += std::string( matchResult[3].first, matchResult[3].second ); + } + + while( !suffix.empty() ) + { + if ( boost::regex_match( suffix.c_str(), matchResult, ptrMatch ) ) + { + lowestType = TypeInfoPtr( new PointerTypeInfo( lowestType, ptrSize ) ); + suffix = std::string(matchResult[1].first, matchResult[1].second ); + continue; + } + + if ( boost::regex_match( suffix.c_str(), matchResult, arrayMatch ) ) + { + lowestType = TypeInfoPtr( new ArrayTypeInfo( lowestType, std::atoi( matchResult[2].first ) ) ); + suffix = std::string(matchResult[1].first, matchResult[1].second ); + continue; + } + } + + if ( !bracketExpr.empty() ) + return getRecurciveComplexType( lowestType, bracketExpr, ptrSize ); + + return lowestType; +} + +///////////////////////////////////////////////////////////////////////////////////// + }; // end namespace pykd \ No newline at end of file diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index 539b0a6..f8b1d7e 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -73,6 +73,12 @@ protected: std::string getComplexName(); + static + TypeInfoPtr getComplexType( pyDia::SymbolPtr &symScope, const std::string &symName ); + + static + TypeInfoPtr getRecurciveComplexType( TypeInfoPtr &lowestType, std::string &suffix, ULONG ptrSize ); + ULONG m_offset; }; @@ -180,6 +186,11 @@ class PointerTypeInfo : public TypeInfo { public: + PointerTypeInfo( const TypeInfoPtr ptr, ULONG ptrSize ) : + m_size( ptrSize ), + m_derefType( ptr ) + {} + PointerTypeInfo( pyDia::SymbolPtr &symbol ); PointerTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName ); @@ -200,7 +211,6 @@ public: return m_derefType; } - private: TypeInfoPtr m_derefType; @@ -214,6 +224,11 @@ class ArrayTypeInfo : public TypeInfo { public: + ArrayTypeInfo( const TypeInfoPtr ptr, ULONG count ) : + m_derefType( ptr ), + m_count( count ) + {} + ArrayTypeInfo( pyDia::SymbolPtr &symbol ); ArrayTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName, ULONG count ); @@ -242,8 +257,6 @@ public: return m_derefType; } - - private: TypeInfoPtr m_derefType; diff --git a/test/scripts/typeinfo.py b/test/scripts/typeinfo.py index b04dbde..c7eb665 100644 --- a/test/scripts/typeinfo.py +++ b/test/scripts/typeinfo.py @@ -18,7 +18,7 @@ class TypeInfoTest( unittest.TestCase ): self.assertEqual( "structTest", target.module.type( "structTest" ).name() ) self.assertEqual( "structTest**", target.module.type( "structTest**" ).name() ) self.assertEqual( "Int4B[2][3]", target.module.type("Int4B[2][3]").name() ) - + self.assertEqual( "Int4B(*[4])[2][3]", target.module.type("Int4B(*[4])[2][3]").name() ) def testCreateBySymbol(self): """ creating typeInfo by the symbol name """