[+] offset into TypeInfo (for fields)

[+] method TypeInfo::build() for recursive typeClass building
[+] virtual method printSelf() for address value for typedVarClass
[~] remove trailing blanks, tabs replaced by spaces


git-svn-id: https://pykd.svn.codeplex.com/svn@61693 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\EreTIk_cp 2011-02-19 15:45:04 +00:00
parent 5879200d07
commit dfbbc434d3
4 changed files with 224 additions and 162 deletions

View File

@ -153,6 +153,7 @@ BOOST_PYTHON_MODULE( pykd )
boost::python::def( "setProcessorMode", &setProcessorMode ); boost::python::def( "setProcessorMode", &setProcessorMode );
boost::python::class_<typeClass, boost::shared_ptr<typeClass> >( "typeClass" ) boost::python::class_<typeClass, boost::shared_ptr<typeClass> >( "typeClass" )
.def("sizeof", &typeClass::size ) .def("sizeof", &typeClass::size )
.def("offset", &typeClass::getOffset )
.def("__str__", &typeClass::print); .def("__str__", &typeClass::print);
boost::python::class_<typedVarClass, boost::python::bases<typeClass>, boost::shared_ptr<typedVarClass> >( "typedVarClass" ) boost::python::class_<typedVarClass, boost::python::bases<typeClass>, boost::shared_ptr<typedVarClass> >( "typedVarClass" )
.def("getAddress", &typedVarClass::getAddress ); .def("getAddress", &typedVarClass::getAddress );
@ -168,7 +169,7 @@ BOOST_PYTHON_MODULE( pykd )
"ext", "ext",
"windbg extension", "windbg extension",
boost::python::init<const char*>( boost::python::args("path"), "__init__ dbgExtensionClass" ) ) boost::python::init<const char*>( boost::python::args("path"), "__init__ dbgExtensionClass" ) )
.def("call", &dbgExtensionClass::call ); .def("call", &dbgExtensionClass::call );
boost::python::class_<dbgStackFrameClass>( "dbgStackFrameClass", "dbgStackFrameClass" ) boost::python::class_<dbgStackFrameClass>( "dbgStackFrameClass", "dbgStackFrameClass" )
.def_readonly( "instructionOffset", &dbgStackFrameClass::InstructionOffset ) .def_readonly( "instructionOffset", &dbgStackFrameClass::InstructionOffset )
.def_readonly( "returnOffset", &dbgStackFrameClass::ReturnOffset ) .def_readonly( "returnOffset", &dbgStackFrameClass::ReturnOffset )

View File

@ -534,10 +534,10 @@ isOffsetValid( ULONG64 addr )
HRESULT hres; HRESULT hres;
try { try {
// íóæíî ïîäàâèòü âîçìîæíûé âûâîä â êîíñîëü îá îòñóòñòâóþùåé ñòðàíèöå ïàìÿòè // íóæíî ïîäàâèòü âîçìîæíûé âûâîä â êîíñîëü îá îòñóòñòâóþùåé ñòðàíèöå ïàìÿòè
OutputReader outputReader( dbgExt->client ); OutputReader outputReader( dbgExt->client );
ULONG offsetInfo; ULONG offsetInfo;
hres = hres =
@ -548,23 +548,23 @@ isOffsetValid( ULONG64 addr )
&offsetInfo, &offsetInfo,
sizeof( offsetInfo ), sizeof( offsetInfo ),
NULL ); NULL );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugDataSpace4::GetOffsetInformation failed" ); throw DbgException( "IDebugDataSpace4::GetOffsetInformation failed" );
return offsetInfo != DEBUG_VSOURCE_INVALID; return offsetInfo != DEBUG_VSOURCE_INVALID;
} }
catch( std::exception &e ) catch( std::exception &e )
{ {
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
} }
catch(...) catch(...)
{ {
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
} }
return false; return false;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////

View File

@ -19,35 +19,34 @@ loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG6
return TypeInfo::get( moduleName, typeName ).load( address ); return TypeInfo::get( moduleName, typeName ).load( address );
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
ULONG ULONG
sizeofType( const std::string &moduleName, const std::string &typeName ) sizeofType( const std::string &moduleName, const std::string &typeName )
{ {
HRESULT hres; HRESULT hres;
ULONG typeSize = ~0; ULONG typeSize = ~0;
try { try {
ULONG64 moduleBase; ULONG64 moduleBase;
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase ); hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" ); throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
typeSize = (ULONG)TypeInfo::get( moduleName, typeName ).size(); typeSize = (ULONG)TypeInfo::get( moduleName, typeName ).size();
} }
catch( std::exception &e )
catch( std::exception &e ) {
{ dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); }
} catch(...)
catch(...) {
{ dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); }
}
return typeSize;
return typeSize;
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
@ -55,38 +54,37 @@ sizeofType( const std::string &moduleName, const std::string &typeName )
boost::python::object boost::python::object
containingRecord( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &fieldName ) containingRecord( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &fieldName )
{ {
HRESULT hres; HRESULT hres;
try { try {
ULONG64 moduleBase; ULONG64 moduleBase;
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase ); hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" ); throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
ULONG typeId; ULONG typeId;
hres = dbgExt->symbols->GetTypeId( moduleBase, typeName.c_str(), &typeId ); hres = dbgExt->symbols->GetTypeId( moduleBase, typeName.c_str(), &typeId );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetTypeId failed" ); throw DbgException( "IDebugSymbol::GetTypeId failed" );
ULONG fieldTypeId; ULONG fieldTypeId;
ULONG fieldOffset; ULONG fieldOffset;
hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName.c_str(), &fieldTypeId, &fieldOffset ); hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName.c_str(), &fieldTypeId, &fieldOffset );
return TypeInfo::get( moduleName, typeName ).load( address - fieldOffset ); return TypeInfo::get( moduleName, typeName ).load( address - fieldOffset );
} }
catch( std::exception &e )
catch( std::exception &e ) {
{ dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() ); }
} catch(...)
catch(...) {
{ dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" ); }
}
return boost::python::object();
return boost::python::object();
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
@ -96,13 +94,7 @@ getTypeClass( const std::string &moduleName, const std::string &typeName )
{ {
try try
{ {
boost::shared_ptr<typeClass> ptr( return TypeInfo::get( moduleName, typeName ).build();
new typeClass( TypeInfo::get( moduleName, typeName ))
);
boost::python::object var( ptr );
ptr->setPyObj(var);
return var;
} }
catch( std::exception &e ) catch( std::exception &e )
{ {
@ -232,14 +224,14 @@ TypeInfo::TypeInfoMap TypeInfo::g_typeInfoCache;
const TypeInfo& const TypeInfo&
TypeInfo::get( const std::string &moduleName, const std::string &typeName ) TypeInfo::get( const std::string &moduleName, const std::string &typeName )
{ {
TypeInfoMap::iterator findIt = g_typeInfoCache.find( TypeName( moduleName, typeName ) ); TypeInfoMap::iterator findIt = g_typeInfoCache.find( TypeName( moduleName, typeName ) );
if ( findIt != g_typeInfoCache.end() ) if ( findIt != g_typeInfoCache.end() )
return findIt->second; return findIt->second;
TypeInfo typeInfo( moduleName, typeName ); TypeInfo typeInfo( moduleName, typeName );
return g_typeInfoCache.insert( std::make_pair( TypeName( moduleName, typeName ), typeInfo) ).first->second; return g_typeInfoCache.insert( std::make_pair( TypeName( moduleName, typeName ), typeInfo) ).first->second;
} }
@ -264,41 +256,41 @@ TypeInfo::setupBaseType()
TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName ) TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName )
{ {
HRESULT hres; HRESULT hres;
m_typeName = typeName; m_typeName = typeName;
m_size = 0; m_size = 0;
m_baseType = false; m_baseType = false;
m_pointer = false; m_pointer = false;
m_offset = 0;
try { try {
if ( typeName.find("*") < typeName.size() ) if ( typeName.find("*") < typeName.size() )
{ {
m_pointer = true; m_pointer = true;
m_size = ptrSize(); m_size = ptrSize();
return; return;
} }
m_baseType = isBaseType( typeName ); m_baseType = isBaseType( typeName );
if ( m_baseType ) if ( m_baseType )
{ {
setupBaseType(); setupBaseType();
return; return;
} }
ULONG64 moduleBase = 0; ULONG64 moduleBase = 0;
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase ); hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" ); throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
ULONG typeId = 0; ULONG typeId = 0;
hres = dbgExt->symbols->GetTypeId( moduleBase, m_typeName.c_str(), &typeId ); hres = dbgExt->symbols->GetTypeId( moduleBase, m_typeName.c_str(), &typeId );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetTypeId failed" );
hres = dbgExt->symbols->GetTypeSize( moduleBase, typeId, &m_size );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetTypeSize failed" ); throw DbgException( "IDebugSymbol::GetTypeId failed" );
hres = dbgExt->symbols->GetTypeSize( moduleBase, typeId, &m_size );
if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
for ( ULONG i = 0; ; ++i ) for ( ULONG i = 0; ; ++i )
{ {
@ -311,41 +303,76 @@ TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName
ULONG fieldTypeId; ULONG fieldTypeId;
ULONG fieldOffset; ULONG fieldOffset;
hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName, &fieldTypeId, &fieldOffset ); hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName, &fieldTypeId, &fieldOffset );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol3::GetFieldTypeAndOffset failed" ); throw DbgException( "IDebugSymbol3::GetFieldTypeAndOffset failed" );
ULONG fieldSize; ULONG fieldSize;
hres = dbgExt->symbols->GetTypeSize( moduleBase, fieldTypeId, &fieldSize ); hres = dbgExt->symbols->GetTypeSize( moduleBase, fieldTypeId, &fieldSize );
if ( FAILED( hres ) ) if ( FAILED( hres ) )
throw DbgException( "IDebugSymbol::GetTypeSize failed" ); throw DbgException( "IDebugSymbol::GetTypeSize failed" );
char fieldTypeName[100]; char fieldTypeName[100];
hres = dbgExt->symbols->GetTypeName( moduleBase, fieldTypeId, fieldTypeName, sizeof(fieldTypeName), NULL ); hres = dbgExt->symbols->GetTypeName( moduleBase, fieldTypeId, fieldTypeName, sizeof(fieldTypeName), NULL );
std::string fieldTypeNameStr( fieldTypeName ); std::string fieldTypeNameStr( fieldTypeName );
if ( fieldTypeNameStr == "__unnamed" if ( fieldTypeNameStr == "__unnamed"
|| fieldTypeNameStr.find("<unnamed-tag>") < fieldTypeNameStr.size() ) || fieldTypeNameStr.find("<unnamed-tag>") < fieldTypeNameStr.size() )
continue; continue;
m_fields.push_back( TypeField( fieldName, get(moduleName, fieldTypeName), fieldSize, fieldOffset ) ); m_fields.push_back( TypeField( fieldName, get(moduleName, fieldTypeName), fieldSize, fieldOffset ) );
} }
}
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" );
} }
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" );
}
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
boost::python::object boost::python::object
TypeInfo::load( ULONG64 addr ) const TypeInfo::build( ULONG offset /* = 0 */ ) const
{
boost::shared_ptr<typeClass> ptr( new typeClass( *this ) );
boost::python::object var( ptr );
ptr->setPyObj( var );
ptr->getTypeInfo().setOffset(offset);
TypeFieldList::const_iterator field = m_fields.begin();
for ( field = m_fields.begin(); field != m_fields.end(); ++field )
{
if ( field->size == field->type.size() )
{
var.attr( field->name.c_str() ) =
field->type.build( offset + field->offset );
}
else
{
boost::python::dict arr;
for ( unsigned int i = 0; i < field->size / field->type.size(); ++i )
{
const ULONG locOffset = field->offset + i * (ULONG)field->type.size();
arr[i] = field->type.build( offset + locOffset );
}
var.attr( field->name.c_str() ) = arr;
}
}
return var;
}
/////////////////////////////////////////////////////////////////////////////////
boost::python::object
TypeInfo::load( ULONG64 addr, ULONG offset /* = 0 */ ) const
{ {
if ( !isOffsetValid( addr) ) if ( !isOffsetValid( addr) )
return boost::python::object(); return boost::python::object();
@ -355,10 +382,11 @@ TypeInfo::load( ULONG64 addr ) const
if ( m_baseType ) if ( m_baseType )
return loadBaseType( addr ); return loadBaseType( addr );
boost::shared_ptr<typedVarClass> ptr( new typedVarClass( *this, addr ) ); boost::shared_ptr<typedVarClass> ptr( new typedVarClass( *this, addr ) );
boost::python::object var( ptr ); boost::python::object var( ptr );
ptr->setPyObj( var ); ptr->setPyObj( var );
ptr->getTypeInfo().setOffset(offset);
TypeFieldList::const_iterator field = m_fields.begin(); TypeFieldList::const_iterator field = m_fields.begin();
for ( field = m_fields.begin(); field != m_fields.end(); ++field ) for ( field = m_fields.begin(); field != m_fields.end(); ++field )
@ -366,19 +394,22 @@ TypeInfo::load( ULONG64 addr ) const
if ( field->size == field->type.size() ) if ( field->size == field->type.size() )
{ {
var.attr( field->name.c_str() ) = field->type.load( addr + field->offset ); var.attr( field->name.c_str() ) =
field->type.load( addr + field->offset, offset + field->offset );
} }
else else
{ {
boost::python::dict arr; boost::python::dict arr;
for ( unsigned int i = 0; i < field->size / field->type.size(); ++i ) for ( unsigned int i = 0; i < field->size / field->type.size(); ++i )
arr[i] = field->type.load( addr + field->offset + i * field->type.size() ); {
const ULONG locOffset = field->offset + i * (ULONG)field->type.size();
var.attr( field->name.c_str() ) = arr; arr[i] = field->type.load( addr + locOffset, offset + locOffset );
} }
}
var.attr( field->name.c_str() ) = arr;
}
}
return var; return var;
} }
@ -392,20 +423,20 @@ isBaseType( const std::string &typeName )
{ {
if ( typeName == basicTypeNames[i] ) if ( typeName == basicTypeNames[i] )
return true; return true;
if ( typeName == ( std::string( basicTypeNames[i] ) + "*" ) ) if ( typeName == ( std::string( basicTypeNames[i] ) + "*" ) )
return true; return true;
if ( typeName == ( std::string( basicTypeNames[i] ) + "[]" ) ) if ( typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
return true; return true;
if ( typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) ) if ( typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) )
return true; return true;
} }
return false; return false;
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
boost::python::object boost::python::object
@ -415,17 +446,17 @@ TypeInfo::loadBaseType( ULONG64 address ) const
{ {
if ( m_typeName == basicTypeNames[i] ) if ( m_typeName == basicTypeNames[i] )
return basicTypeLoaders[i]( address, m_size ); return basicTypeLoaders[i]( address, m_size );
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "*" ) ) if ( m_typeName == ( std::string( basicTypeNames[i] ) + "*" ) )
return valueLoader<void*>( address, ptrSize() ); return valueLoader<void*>( address, ptrSize() );
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "[]" ) ) if ( m_typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
return basicTypeLoaders[i]( address, m_size ); return basicTypeLoaders[i]( address, m_size );
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) ) if ( m_typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) )
return valueLoader<void*>( address, ptrSize() ); return valueLoader<void*>( address, ptrSize() );
} }
return boost::python::object(); return boost::python::object();
} }
@ -444,16 +475,16 @@ valueLoader( ULONG64 address, ULONG size )
else else
{ {
boost::python::dict arr; boost::python::dict arr;
for ( unsigned int i = 0; i < size / sizeof(valType); ++i ) for ( unsigned int i = 0; i < size / sizeof(valType); ++i )
{ {
valType v = 0; valType v = 0;
if ( !loadMemory( address + i * sizeof(valType), &v, sizeof(v) ) ) if ( !loadMemory( address + i * sizeof(valType), &v, sizeof(v) ) )
return boost::python::object(); return boost::python::object();
arr[i] = boost::python::long_( (unsigned __int64)v ); arr[i] = boost::python::long_( (unsigned __int64)v );
} }
return arr; return arr;
} }
@ -466,14 +497,17 @@ std::string typeClass::print() const
{ {
stringstream sstr; stringstream sstr;
sstr << getTypeInfo().name() << std::endl; sstr << getTypeInfo().name() << " ";
printSelf(sstr);
sstr << std::endl;
TypeInfo::TypeFieldList::const_iterator itField = TypeInfo::TypeFieldList::const_iterator itField =
getTypeInfo().getFields().begin(); getTypeInfo().getFields().begin();
while (itField != getTypeInfo().getFields().end()) while (itField != getTypeInfo().getFields().end())
{ {
sstr << "\t" << hex << "+" << itField->offset; sstr << "\t" << hex << "+" << itField->offset << " ";
sstr << " " << itField->name << " "; sstr << itField->type.name() << " ";
sstr << itField->name << " ";
printField(*itField, sstr); printField(*itField, sstr);
@ -495,7 +529,7 @@ typedVarClass::printField(const TypeInfo::TypeField &field, stringstream &sstr)
else else
{ {
boost::python::object attr = getPyObj().attr( field.name.c_str() ); boost::python::object attr = getPyObj().attr( field.name.c_str() );
if ( field.size == field.type.size() ) if ( field.size == field.type.size() )
{ {
if ( attr.ptr() == Py_None ) if ( attr.ptr() == Py_None )
@ -505,9 +539,9 @@ typedVarClass::printField(const TypeInfo::TypeField &field, stringstream &sstr)
else else
{ {
unsigned __int64 val = boost::python::extract<unsigned __int64>( attr ); unsigned __int64 val = boost::python::extract<unsigned __int64>( attr );
sstr << hex << "0x" << val; sstr << hex << "0x" << val;
if ( field.type.name() == "char*" ) if ( field.type.name() == "char*" )
{ {
char buf[0x100]; char buf[0x100];
@ -522,20 +556,20 @@ typedVarClass::printField(const TypeInfo::TypeField &field, stringstream &sstr)
if ( loadWStrToBuffer( val, wbuf, sizeof(wbuf) ) ) if ( loadWStrToBuffer( val, wbuf, sizeof(wbuf) ) )
{ {
char mbBuf[0x100] = { 0 }; char mbBuf[0x100] = { 0 };
WideCharToMultiByte( CP_ACP, 0, wbuf, wcslen(wbuf)+1, mbBuf, sizeof(mbBuf), NULL, NULL ); WideCharToMultiByte( CP_ACP, 0, wbuf, wcslen(wbuf)+1, mbBuf, sizeof(mbBuf), NULL, NULL );
sstr << " (" << mbBuf << " )"; sstr << " (" << mbBuf << " )";
} }
else else
sstr << " ( read string error )"; sstr << " ( read string error )";
} }
else else
{ {
sstr << dec << " ( " << val << " )"; sstr << dec << " ( " << val << " )";
} }
} }
} }
else else
{ {
for ( size_t i = 0; i < field.size/field.type.size(); ++i ) for ( size_t i = 0; i < field.size/field.type.size(); ++i )

View File

@ -38,11 +38,11 @@ public:
template< typename TTypeInfo> template< typename TTypeInfo>
struct TypeFieldT { struct TypeFieldT {
ULONG size; ULONG size;
ULONG offset; ULONG offset;
TTypeInfo type; TTypeInfo type;
std::string name; std::string name;
TypeFieldT( const std::string &name_, const TTypeInfo &type_, ULONG size_, ULONG offset_ ) : TypeFieldT( const std::string &name_, const TTypeInfo &type_, ULONG size_, ULONG offset_ ) :
name( name_ ), name( name_ ),
size( size_ ), size( size_ ),
@ -65,12 +65,12 @@ public:
if ( typeName.module < module ) if ( typeName.module < module )
return true; return true;
if ( typeName.module > module ) if ( typeName.module > module )
return false; return false;
return typeName.symbol < symbol; return typeName.symbol < symbol;
} }
}; };
@ -85,46 +85,55 @@ public:
TypeInfo() : TypeInfo() :
m_size( 0 ), m_size( 0 ),
m_baseType( false ), m_baseType( false ),
m_pointer( false ) m_pointer( false ),
m_offset(0)
{} {}
TypeInfo( const std::string &moduleName, const std::string &typeName ); TypeInfo( const std::string &moduleName, const std::string &typeName );
boost::python::object boost::python::object
load( ULONG64 addr ) const; load( ULONG64 addr, ULONG offset = 0 ) const;
boost::python::object
build( ULONG offset = 0 ) const;
ULONG64 ULONG64
size() const size() const
{ {
return m_size; return m_size;
} }
const std::string& const std::string&
name() const name() const
{ {
return m_typeName; return m_typeName;
} }
static const TypeInfo& static const TypeInfo&
get( const std::string &moduleName, const std::string &typeName ); get( const std::string &moduleName, const std::string &typeName );
const TypeFieldList& const TypeFieldList&
getFields() const { getFields() const {
return m_fields; return m_fields;
} }
bool bool
isComplex() const { isComplex() const {
return !m_baseType; return !m_baseType;
} }
bool bool
isPtr() const { isPtr() const {
return m_pointer; return m_pointer;
} }
private: // field offset getter/setter
void setOffset(ULONG offset) { m_offset = offset; }
ULONG getOffset() const { return m_offset; }
private:
static TypeInfoMap g_typeInfoCache; static TypeInfoMap g_typeInfoCache;
boost::python::object boost::python::object
@ -134,7 +143,7 @@ private:
ptrLoader( ULONG64 addr ) const { ptrLoader( ULONG64 addr ) const {
return boost::python::object( loadPtrByPtr( addr ) ); return boost::python::object( loadPtrByPtr( addr ) );
} }
void void
setupBaseType(); setupBaseType();
@ -145,6 +154,7 @@ private:
TypeFieldList m_fields; TypeFieldList m_fields;
std::string m_typeName; std::string m_typeName;
ULONG m_size; ULONG m_size;
ULONG m_offset;
}; };
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
@ -163,9 +173,10 @@ public:
{ {
} }
// sizeof(TYPE)
ULONG size() const ULONG size() const
{ {
return m_typeInfo.size(); return (ULONG)m_typeInfo.size();
} }
void setPyObj( const boost::python::object &obj ) void setPyObj( const boost::python::object &obj )
@ -173,6 +184,7 @@ public:
m_pyobj = obj; m_pyobj = obj;
} }
// TypeInfo getter
TypeInfo &getTypeInfo() TypeInfo &getTypeInfo()
{ {
return m_typeInfo; return m_typeInfo;
@ -182,6 +194,7 @@ public:
return m_typeInfo; return m_typeInfo;
} }
// boost::python::object getter
boost::python::object &getPyObj() boost::python::object &getPyObj()
{ {
return m_pyobj; return m_pyobj;
@ -200,6 +213,14 @@ public:
{ {
// no data - nothing print // no data - nothing print
} }
virtual void printSelf(
std::stringstream &sstr
) const
{
// no data - nothing print
}
ULONG getOffset() const { return m_typeInfo.getOffset(); }
private: private:
TypeInfo m_typeInfo; TypeInfo m_typeInfo;
@ -226,7 +247,13 @@ public:
} }
virtual void virtual void
printField(const TypeInfo::TypeField &field, std::stringstream &sstr) const override; printField( const TypeInfo::TypeField &field, std::stringstream &sstr ) const override;
virtual void
printSelf( std::stringstream &sstr ) const override
{
sstr << std::hex << "0x" << getAddress() << std::dec << " ";
}
private: private: