mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +08:00
[!] fixed : issue #6782 ( typedVar works very slowly )
git-svn-id: https://pykd.svn.codeplex.com/svn@59199 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
b94835d808
commit
f087707c2c
471
pykd/dbgtype.cpp
471
pykd/dbgtype.cpp
@ -10,172 +10,31 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
bool
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
isBaseType( const std::string &typeName );
|
|
||||||
|
|
||||||
boost::python::object
|
|
||||||
loadBaseType( const std::string &typeName, ULONG64 address, ULONG size );
|
|
||||||
|
|
||||||
typedef
|
|
||||||
boost::python::object
|
|
||||||
(*basicTypeLoader)( ULONG64 address, ULONG size );
|
|
||||||
|
|
||||||
boost::python::object
|
|
||||||
voidLoader( ULONG64 address, ULONG size ) {
|
|
||||||
return boost::python::object();
|
|
||||||
}
|
|
||||||
|
|
||||||
template< typename valType>
|
|
||||||
boost::python::object
|
|
||||||
valueLoader( ULONG64 address, ULONG size );
|
|
||||||
|
|
||||||
template<>
|
|
||||||
boost::python::object
|
|
||||||
valueLoader<void*>( ULONG64 address, ULONG size )
|
|
||||||
{
|
|
||||||
if ( is64bitSystem() )
|
|
||||||
return valueLoader<__int64>( address, size );
|
|
||||||
else
|
|
||||||
return valueLoader<long>( address, size );
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char*
|
|
||||||
basicTypeNames[] = {
|
|
||||||
"unsigned char",
|
|
||||||
"char",
|
|
||||||
"unsigned short",
|
|
||||||
"short",
|
|
||||||
"unsigned long",
|
|
||||||
"long",
|
|
||||||
"int",
|
|
||||||
"unsigned int",
|
|
||||||
"<function>",
|
|
||||||
"void",
|
|
||||||
"double",
|
|
||||||
"int64",
|
|
||||||
"unsigned int64"
|
|
||||||
};
|
|
||||||
|
|
||||||
basicTypeLoader basicTypeLoaders[] = {
|
|
||||||
valueLoader<unsigned char>,
|
|
||||||
valueLoader<char>,
|
|
||||||
valueLoader<unsigned short>,
|
|
||||||
valueLoader<short>,
|
|
||||||
valueLoader<unsigned long>,
|
|
||||||
valueLoader<long>,
|
|
||||||
valueLoader<int>,
|
|
||||||
valueLoader<unsigned int>,
|
|
||||||
valueLoader<void*>,
|
|
||||||
voidLoader,
|
|
||||||
valueLoader<double>,
|
|
||||||
valueLoader<__int64>,
|
|
||||||
valueLoader<unsigned __int64>
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG64 address )
|
loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG64 address )
|
||||||
|
{
|
||||||
|
return TypeInfo::get( moduleName, typeName ).load( address );
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
sizeofType( const std::string &moduleName, const std::string &typeName )
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
ULONG typeSize = ~0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if ( address == 0 )
|
|
||||||
return boost::python::object();
|
|
||||||
|
|
||||||
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;
|
typeSize = (ULONG)TypeInfo::get( moduleName, typeName ).size();
|
||||||
hres = dbgExt->symbols->GetTypeId( moduleBase, typeName.c_str(), &typeId );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
|
||||||
|
|
||||||
ULONG typeSize;
|
|
||||||
hres = dbgExt->symbols->GetTypeSize( moduleBase, typeId, &typeSize );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
|
||||||
|
|
||||||
typedVarClass temp( address, typeSize );
|
|
||||||
boost::python::object var( temp );
|
|
||||||
|
|
||||||
for ( ULONG i = 0; ; ++i )
|
|
||||||
{
|
|
||||||
char fieldName[100];
|
|
||||||
hres = dbgExt->symbols2->GetFieldName( moduleBase, typeId, i, fieldName, sizeof(fieldName), NULL );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
break;
|
|
||||||
|
|
||||||
ULONG fieldTypeId;
|
|
||||||
ULONG fieldOffset;
|
|
||||||
hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName, &fieldTypeId, &fieldOffset );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol3::GetFieldTypeAndOffset failed" );
|
|
||||||
|
|
||||||
char fieldTypeName[100];
|
|
||||||
hres = dbgExt->symbols->GetTypeName( moduleBase, fieldTypeId, fieldTypeName, sizeof(fieldTypeName), NULL );
|
|
||||||
|
|
||||||
std::string fieldTypeNameStr( fieldTypeName );
|
|
||||||
if ( fieldTypeNameStr == "__unnamed"
|
|
||||||
|| fieldTypeNameStr.find("<unnamed-tag>") < fieldTypeNameStr.size() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ULONG fieldSize;
|
|
||||||
hres = dbgExt->symbols->GetTypeSize( moduleBase, fieldTypeId, &fieldSize );
|
|
||||||
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol::GetTypeName failed" );
|
|
||||||
|
|
||||||
if ( isBaseType( fieldTypeName ) )
|
|
||||||
{
|
|
||||||
var.attr( fieldName ) = loadBaseType( fieldTypeName, address + fieldOffset, fieldSize );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string fieldTypeNameStr( fieldTypeName );
|
|
||||||
|
|
||||||
if ( fieldTypeNameStr.find("*") < fieldTypeNameStr.size() )
|
|
||||||
{
|
|
||||||
var.attr( fieldName ) = valueLoader<void*>( address + fieldOffset, fieldSize );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if ( fieldTypeNameStr.find("[]") < fieldTypeNameStr.size() )
|
|
||||||
{
|
|
||||||
std::string arrayElemType = std::string( fieldTypeNameStr, 0, fieldTypeNameStr.size() - 2 );
|
|
||||||
|
|
||||||
ULONG arrayElemTypeId;
|
|
||||||
hres = dbgExt->symbols->GetTypeId( moduleBase, arrayElemType.c_str(), &arrayElemTypeId );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
|
||||||
|
|
||||||
ULONG arayElemTypeSize;
|
|
||||||
hres = dbgExt->symbols->GetTypeSize( moduleBase, arrayElemTypeId, &arayElemTypeSize );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
|
||||||
|
|
||||||
boost::python::dict arr;
|
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < typeSize / sizeof(arayElemTypeSize); ++i )
|
|
||||||
arr[i] = loadTypedVar( moduleName, arrayElemType, address + fieldOffset + i * arayElemTypeSize );
|
|
||||||
|
|
||||||
var.attr( fieldName ) = arr;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var.attr( fieldName ) = loadTypedVar( moduleName, fieldTypeName, address + fieldOffset );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return var;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch( std::exception &e )
|
catch( std::exception &e )
|
||||||
@ -187,10 +46,10 @@ loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG6
|
|||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return boost::python::str( "VAR_ERR" );
|
return typeSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
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 )
|
||||||
@ -214,7 +73,7 @@ containingRecord( ULONG64 address, const std::string &moduleName, const std::str
|
|||||||
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 loadTypedVar( moduleName, typeName, address - fieldOffset );
|
return TypeInfo::get( moduleName, typeName ).load( address - fieldOffset );
|
||||||
}
|
}
|
||||||
|
|
||||||
catch( std::exception &e )
|
catch( std::exception &e )
|
||||||
@ -226,48 +85,10 @@ containingRecord( ULONG64 address, const std::string &moduleName, const std::str
|
|||||||
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return boost::python::str( "VAR_ERR" );
|
return boost::python::object();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG
|
|
||||||
sizeofType( const std::string &moduleName, const std::string &typeName )
|
|
||||||
{
|
|
||||||
HRESULT hres;
|
|
||||||
ULONG typeSize = ~0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
ULONG64 moduleBase;
|
|
||||||
|
|
||||||
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
|
||||||
|
|
||||||
ULONG typeId;
|
|
||||||
hres = dbgExt->symbols->GetTypeId( moduleBase, typeName.c_str(), &typeId );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol::GetTypeId failed" );
|
|
||||||
|
|
||||||
hres = dbgExt->symbols->GetTypeSize( moduleBase, typeId, &typeSize );
|
|
||||||
if ( FAILED( hres ) )
|
|
||||||
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
|
||||||
}
|
|
||||||
|
|
||||||
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 typeSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
loadTypedVarList( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &listEntryName )
|
loadTypedVarList( ULONG64 address, const std::string &moduleName, const std::string &typeName, const std::string &listEntryName )
|
||||||
@ -284,7 +105,237 @@ loadTypedVarList( ULONG64 address, const std::string &moduleName, const std::str
|
|||||||
return objList;
|
return objList;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool
|
||||||
|
isBaseType( const std::string &typeName );
|
||||||
|
|
||||||
|
template< typename valType>
|
||||||
|
boost::python::object
|
||||||
|
valueLoader( ULONG64 address, ULONG size );
|
||||||
|
|
||||||
|
template<>
|
||||||
|
boost::python::object
|
||||||
|
valueLoader<void*>( ULONG64 address, ULONG size )
|
||||||
|
{
|
||||||
|
if ( is64bitSystem() )
|
||||||
|
return valueLoader<__int64>( address, size );
|
||||||
|
else
|
||||||
|
return valueLoader<long>( address, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
voidLoader( ULONG64 address, ULONG size ) {
|
||||||
|
return boost::python::object();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
basicTypeNames[] = {
|
||||||
|
"unsigned char",
|
||||||
|
"char",
|
||||||
|
"unsigned short",
|
||||||
|
"short",
|
||||||
|
"unsigned long",
|
||||||
|
"long",
|
||||||
|
"int",
|
||||||
|
"unsigned int",
|
||||||
|
"<function>",
|
||||||
|
"void",
|
||||||
|
"double",
|
||||||
|
"int64",
|
||||||
|
"unsigned int64",
|
||||||
|
"ptr"
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef
|
||||||
|
boost::python::object
|
||||||
|
(*basicTypeLoader)( ULONG64 address, ULONG size );
|
||||||
|
|
||||||
|
basicTypeLoader basicTypeLoaders[] = {
|
||||||
|
valueLoader<unsigned char>,
|
||||||
|
valueLoader<char>,
|
||||||
|
valueLoader<unsigned short>,
|
||||||
|
valueLoader<short>,
|
||||||
|
valueLoader<unsigned long>,
|
||||||
|
valueLoader<long>,
|
||||||
|
valueLoader<int>,
|
||||||
|
valueLoader<unsigned int>,
|
||||||
|
valueLoader<void*>,
|
||||||
|
voidLoader,
|
||||||
|
valueLoader<double>,
|
||||||
|
valueLoader<__int64>,
|
||||||
|
valueLoader<unsigned __int64>
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t basicTypeSizes[] = {
|
||||||
|
sizeof( unsigned char ),
|
||||||
|
sizeof( char ),
|
||||||
|
sizeof( unsigned short ),
|
||||||
|
sizeof( short ),
|
||||||
|
sizeof( unsigned long ),
|
||||||
|
sizeof( long ),
|
||||||
|
sizeof( int ),
|
||||||
|
sizeof( unsigned int ),
|
||||||
|
sizeof( void* ),
|
||||||
|
0,
|
||||||
|
sizeof( double ),
|
||||||
|
sizeof( __int64 ),
|
||||||
|
sizeof( unsigned __int64 )
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypeInfo::TypeInfoMap TypeInfo::g_typeInfoCache;
|
||||||
|
|
||||||
|
const TypeInfo&
|
||||||
|
TypeInfo::get( const std::string &moduleName, const std::string &typeName )
|
||||||
|
{
|
||||||
|
TypeInfoMap::iterator findIt = g_typeInfoCache.find( TypeName( moduleName, typeName ) );
|
||||||
|
|
||||||
|
if ( findIt != g_typeInfoCache.end() )
|
||||||
|
return findIt->second;
|
||||||
|
|
||||||
|
TypeInfo typeInfo( moduleName, typeName );
|
||||||
|
|
||||||
|
return g_typeInfoCache.insert( std::make_pair( TypeName( moduleName, typeName ), typeInfo) ).first->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void
|
||||||
|
TypeInfo::setupBaseType()
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < sizeof( basicTypeSizes ) / sizeof( size_t ); ++i )
|
||||||
|
{
|
||||||
|
if ( m_typeName == basicTypeNames[i] ||
|
||||||
|
m_typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
|
||||||
|
{
|
||||||
|
m_size = (ULONG)basicTypeSizes[i];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypeInfo::TypeInfo( const std::string &moduleName, const std::string &typeName )
|
||||||
|
{
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
m_typeName = typeName;
|
||||||
|
m_size = 0;
|
||||||
|
m_baseType = false;
|
||||||
|
m_pointer = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if ( typeName.find("*") < typeName.size() )
|
||||||
|
{
|
||||||
|
m_pointer = true;
|
||||||
|
m_size = ptrSize();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_baseType = isBaseType( typeName );
|
||||||
|
if ( m_baseType )
|
||||||
|
{
|
||||||
|
setupBaseType();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG64 moduleBase = 0;
|
||||||
|
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
||||||
|
|
||||||
|
ULONG typeId = 0;
|
||||||
|
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 ) )
|
||||||
|
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
||||||
|
|
||||||
|
for ( ULONG i = 0; ; ++i )
|
||||||
|
{
|
||||||
|
char fieldName[100];
|
||||||
|
hres = dbgExt->symbols2->GetFieldName( moduleBase, typeId, i, fieldName, sizeof(fieldName), NULL );
|
||||||
|
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
ULONG fieldTypeId;
|
||||||
|
ULONG fieldOffset;
|
||||||
|
hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName, &fieldTypeId, &fieldOffset );
|
||||||
|
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugSymbol3::GetFieldTypeAndOffset failed" );
|
||||||
|
|
||||||
|
ULONG fieldSize;
|
||||||
|
hres = dbgExt->symbols->GetTypeSize( moduleBase, fieldTypeId, &fieldSize );
|
||||||
|
if ( FAILED( hres ) )
|
||||||
|
throw DbgException( "IDebugSymbol::GetTypeSize failed" );
|
||||||
|
|
||||||
|
char fieldTypeName[100];
|
||||||
|
hres = dbgExt->symbols->GetTypeName( moduleBase, fieldTypeId, fieldTypeName, sizeof(fieldTypeName), NULL );
|
||||||
|
|
||||||
|
std::string fieldTypeNameStr( fieldTypeName );
|
||||||
|
if ( fieldTypeNameStr == "__unnamed"
|
||||||
|
|| fieldTypeNameStr.find("<unnamed-tag>") < fieldTypeNameStr.size() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_fields.insert( make_pair( fieldName, TypeField( 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" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
TypeInfo::load( ULONG64 addr ) const
|
||||||
|
{
|
||||||
|
if ( m_pointer )
|
||||||
|
return ptrLoader( addr );
|
||||||
|
|
||||||
|
if ( m_baseType )
|
||||||
|
return loadBaseType( addr );
|
||||||
|
|
||||||
|
boost::python::object var( typedVarClass( addr, m_size ) );
|
||||||
|
|
||||||
|
TypeFieldMap::const_iterator it = m_fields.begin();
|
||||||
|
for ( it = m_fields.begin(); it != m_fields.end(); ++it )
|
||||||
|
{
|
||||||
|
const TypeField &field = it->second;
|
||||||
|
|
||||||
|
if ( field.size == field.type.size() )
|
||||||
|
{
|
||||||
|
var.attr( it->first.c_str() ) = field.type.load( addr + field.offset );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boost::python::dict arr;
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < field.size / field.type.size(); ++i )
|
||||||
|
arr[i] = field.type.load( addr + field.offset + i * field.type.size() );
|
||||||
|
|
||||||
|
var.attr( it->first.c_str() ) = arr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool
|
bool
|
||||||
isBaseType( const std::string &typeName )
|
isBaseType( const std::string &typeName )
|
||||||
@ -307,32 +358,30 @@ isBaseType( const std::string &typeName )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
boost::python::object
|
boost::python::object
|
||||||
loadBaseType( const std::string &typeName, ULONG64 address, ULONG size )
|
TypeInfo::loadBaseType( ULONG64 address ) const
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < sizeof( basicTypeNames ) / sizeof( char* ); ++i )
|
for ( int i = 0; i < sizeof( basicTypeNames ) / sizeof( char* ); ++i )
|
||||||
{
|
{
|
||||||
if ( typeName == basicTypeNames[i] )
|
if ( m_typeName == basicTypeNames[i] )
|
||||||
return basicTypeLoaders[i]( address, size );
|
return basicTypeLoaders[i]( address, m_size );
|
||||||
|
|
||||||
if ( typeName == ( std::string( basicTypeNames[i] ) + "*" ) )
|
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "*" ) )
|
||||||
return valueLoader<void*>( address, size );
|
return valueLoader<void*>( address, ptrSize() );
|
||||||
|
|
||||||
if ( typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
|
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "[]" ) )
|
||||||
return basicTypeLoaders[i]( address, size );
|
return basicTypeLoaders[i]( address, m_size );
|
||||||
|
|
||||||
if ( typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) )
|
if ( m_typeName == ( std::string( basicTypeNames[i] ) + "*[]" ) )
|
||||||
return valueLoader<void*>( address, size );
|
return valueLoader<void*>( address, ptrSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return boost::python::object();
|
return boost::python::object();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template< typename valType>
|
template< typename valType>
|
||||||
boost::python::object
|
boost::python::object
|
||||||
@ -363,6 +412,4 @@ valueLoader( ULONG64 address, ULONG size )
|
|||||||
return boost::python::object();
|
return boost::python::object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
100
pykd/dbgtype.h
100
pykd/dbgtype.h
@ -1,10 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
#include <boost/python/object.hpp>
|
#include <boost/python/object.hpp>
|
||||||
|
|
||||||
|
#include "dbgmem.h"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class typedVarClass {
|
class typedVarClass {
|
||||||
@ -52,4 +55,101 @@ ULONG
|
|||||||
sizeofType( const std::string &moduleName, const std::string &typeName );
|
sizeofType( const std::string &moduleName, const std::string &typeName );
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class TypeInfo {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeInfo() :
|
||||||
|
m_size( 0 ),
|
||||||
|
m_baseType( false ),
|
||||||
|
m_pointer( false )
|
||||||
|
{}
|
||||||
|
|
||||||
|
TypeInfo( const std::string &moduleName, const std::string &typeName );
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
load( ULONG64 addr ) const;
|
||||||
|
|
||||||
|
ULONG64
|
||||||
|
size() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string&
|
||||||
|
name() const
|
||||||
|
{
|
||||||
|
return m_typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo&
|
||||||
|
get( const std::string &moduleName, const std::string &typeName );
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
template< typename TTypeInfo>
|
||||||
|
struct TypeFieldT {
|
||||||
|
ULONG size;
|
||||||
|
ULONG offset;
|
||||||
|
TTypeInfo type;
|
||||||
|
|
||||||
|
TypeFieldT( const TTypeInfo &type_, ULONG size_, ULONG offset_ ) :
|
||||||
|
size( size_ ),
|
||||||
|
offset( offset_ ),
|
||||||
|
type( type_ )
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TypeName {
|
||||||
|
std::string module;
|
||||||
|
std::string symbol;
|
||||||
|
|
||||||
|
TypeName( const std::string &module_, const std::string &symbol_ ) :
|
||||||
|
module( module_ ),
|
||||||
|
symbol( symbol_ )
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool
|
||||||
|
operator < ( const TypeName &typeName ) const {
|
||||||
|
return ( typeName.module <= module ) && ( typeName.symbol < symbol );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef TypeFieldT<TypeInfo> TypeField;
|
||||||
|
|
||||||
|
typedef std::map<TypeName, TypeInfo> TypeInfoMap;
|
||||||
|
|
||||||
|
typedef std::map<std::string, TypeField> TypeFieldMap;
|
||||||
|
|
||||||
|
static TypeInfoMap g_typeInfoCache;
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
loadBaseType( ULONG64 addr ) const;
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
ptrLoader( ULONG64 addr ) const {
|
||||||
|
return boost::python::object( loadPtrByPtr( addr ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setupBaseType();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool m_baseType;
|
||||||
|
|
||||||
|
bool m_pointer;
|
||||||
|
|
||||||
|
TypeFieldMap m_fields;
|
||||||
|
|
||||||
|
std::string m_typeName;
|
||||||
|
|
||||||
|
ULONG m_size;
|
||||||
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
@ -132,6 +132,7 @@
|
|||||||
GeneratePreprocessedFile="0"
|
GeneratePreprocessedFile="0"
|
||||||
KeepComments="false"
|
KeepComments="false"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
|
ExceptionHandling="2"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
UsePrecompiledHeader="2"
|
UsePrecompiledHeader="2"
|
||||||
|
Loading…
Reference in New Issue
Block a user