From 15b5736adf2591cc3f9ef2b1ef0c0fca86bc546a Mon Sep 17 00:00:00 2001 From: "SND\\EreTIk_cp" Date: Wed, 18 Jan 2012 15:20:20 +0000 Subject: [PATCH] [0.1.x] ~ [wi:10168] filelds from base class ~ list entry to addr64 git-svn-id: https://pykd.svn.codeplex.com/svn@73277 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/module.cpp | 4 +- pykd/typeinfo.cpp | 119 ++++++++++++++++++++++++++++++++++++++-------- pykd/typeinfo.h | 18 ++++--- 3 files changed, 112 insertions(+), 29 deletions(-) diff --git a/pykd/module.cpp b/pykd/module.cpp index 4bf34e8..6feb299 100644 --- a/pykd/module.cpp +++ b/pykd/module.cpp @@ -327,12 +327,12 @@ python::list Module::getTypedVarListByType( ULONG64 listHeadAddress, const TypeI if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) ) { - for( entryAddress = ptrPtr( listHeadAddress ); entryAddress != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + fieldTypeInfo->getOffset() ) ) + for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + fieldTypeInfo->getOffset() ) ) lst.append( getTypedVarByType( typeInfo, entryAddress ) ); } else { - for( entryAddress = ptrPtr( listHeadAddress ); entryAddress != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) ) + for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) ) lst.append( containingRecordByType( entryAddress, typeInfo, listEntryName ) ); } diff --git a/pykd/typeinfo.cpp b/pykd/typeinfo.cpp index f58e0d3..83f6ac0 100644 --- a/pykd/typeinfo.cpp +++ b/pykd/typeinfo.cpp @@ -73,7 +73,6 @@ BaseTypeVariant TypeInfo::getValue() TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName ) { size_t pos = symName.find_first_of( "*[" ); - CComVariant constVal; if ( pos == std::string::npos ) { @@ -81,31 +80,37 @@ TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &symScope, const std::strin if ( basePtr != 0 ) return basePtr; - pyDia::SymbolPtr typeSym = symScope->getChildByName( symName ); + return getTypeInfo( symScope, symScope->getChildByName( symName ) ); + } - if ( typeSym->getSymTag() == SymTagData ) + return getComplexType( symScope, symName ); +} + +///////////////////////////////////////////////////////////////////////////////////// + +TypeInfoPtr TypeInfo::getTypeInfo( pyDia::SymbolPtr &symScope, pyDia::SymbolPtr symChild ) +{ + CComVariant constVal; + if ( symChild->getSymTag() == SymTagData ) + { + if ( symChild->getLocType() == LocIsBitField ) { - if ( typeSym->getLocType() == LocIsBitField ) - { - return TypeInfoPtr( new BitFieldTypeInfo(typeSym) ); - } - - if ( typeSym->getDataKind() == DataIsConstant ) - { - typeSym->getValue( constVal ); - } - - typeSym = typeSym->getType(); + return TypeInfoPtr( new BitFieldTypeInfo(symChild) ); } - TypeInfoPtr ptr = getTypeInfo( typeSym ); + if ( symChild->getDataKind() == DataIsConstant ) + { + symChild->getValue( constVal ); + } - ptr->setConstant( constVal ); - - return ptr; + symChild = symChild->getType(); } - - return getComplexType( symScope, symName ); + + TypeInfoPtr ptr = getTypeInfo( symChild ); + + ptr->setConstant( constVal ); + + return ptr; } ///////////////////////////////////////////////////////////////////////////////////// @@ -337,7 +342,7 @@ TypeInfoPtr TypeInfo::getComplexType( pyDia::SymbolPtr &symScope, const std::str boost::cmatch matchResult; if ( !boost::regex_match( symName.c_str(), matchResult, typeMatch ) ) - TypeException( symName, "type name is invalid" ); + throw TypeException( symName, "type name is invalid" ); TypeInfoPtr lowestTypeInfo = getTypeInfo( symScope, std::string( matchResult[1].first, matchResult[1].second ) ); @@ -390,6 +395,78 @@ TypeInfoPtr TypeInfo::getRecurciveComplexType( TypeInfoPtr &lowestType, std::str ///////////////////////////////////////////////////////////////////////////////////// +TypeInfoPtr UdtTypeInfo::getField( const std::string &fieldName ) +{ + pyDia::SymbolPtr field; + LONG addOffset = 0; + try + { + field = m_dia->getChildByName( fieldName ); + } + catch (const pyDia::Exception &) + { + } + + if ( !field && !getBaseField( m_dia, fieldName, addOffset, field ) ) + throw TypeException( m_dia->getName(), fieldName + ": field not found" ); + + TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, field ); + ti->setOffset( addOffset + field->getOffset() ); + return ti; +} + +///////////////////////////////////////////////////////////////////////////////////// + +bool +UdtTypeInfo::getBaseField( + pyDia::SymbolPtr symUdt, + const std::string &fieldName, + LONG &addOffset, + pyDia::SymbolPtr &symField, + ULONG currLevel /*= 0*/ +) +{ + if (currLevel > 16) + return false; + + LONG currOffset = 0; + + pyDia::SymbolPtrList lstBases = symUdt->findChildrenImpl(SymTagBaseClass); + pyDia::SymbolPtrList::iterator it = lstBases.begin(); + for (; it != lstBases.end(); ++it) + { + // find in direct base + try + { + symField = (*it)->getChildByName( fieldName ); + addOffset += currOffset; + return true; + } + catch (const pyDia::Exception &) + { + } + + // find in base of base + try + { + if (getBaseField(*it, fieldName, addOffset, symField, currLevel + 1)) + { + addOffset += currOffset; + return true; + } + } + catch (const pyDia::Exception &) + { + } + + // correct offset + currOffset += static_cast( (*it)->getSize() ); + } + return false; +} + +///////////////////////////////////////////////////////////////////////////////////// + python::dict EnumTypeInfo::asMap() { python::dict dct; diff --git a/pykd/typeinfo.h b/pykd/typeinfo.h index 2aa35d7..bb2812b 100644 --- a/pykd/typeinfo.h +++ b/pykd/typeinfo.h @@ -21,6 +21,9 @@ public: static TypeInfoPtr getTypeInfo( pyDia::SymbolPtr &symScope, const std::string &symName ); + static + TypeInfoPtr getTypeInfo( pyDia::SymbolPtr &symScope, pyDia::SymbolPtr symChild ); + static TypeInfoPtr getTypeInfo( pyDia::SymbolPtr &symbol ); @@ -205,17 +208,20 @@ protected: return (ULONG)m_dia->getSize(); } - virtual TypeInfoPtr getField( const std::string &fieldName ) { - pyDia::SymbolPtr field = m_dia->getChildByName( fieldName ); - TypeInfoPtr ti = TypeInfo::getTypeInfo( m_dia, fieldName ); - ti->setOffset( field->getOffset() ); - return ti; - } + virtual TypeInfoPtr getField( const std::string &fieldName ); virtual bool isUserDefined() { return true; } + static bool getBaseField( + pyDia::SymbolPtr symUdt, + const std::string &fieldName, + LONG &addOffset, + pyDia::SymbolPtr &symField, + ULONG currLevel = 0 + ); + pyDia::SymbolPtr m_dia; };