mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[0.2.x] added : typedVar class
git-svn-id: https://pykd.svn.codeplex.com/svn@78536 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
011f1b4ad5
commit
c8d99b5565
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "dbgmem.h"
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
// manage debug target
|
// manage debug target
|
||||||
@ -22,10 +24,8 @@ std::string getModuleSymbolFileName( ULONG64 baseOffset );
|
|||||||
ULONG getModuleTimeStamp( ULONG64 baseOffset );
|
ULONG getModuleTimeStamp( ULONG64 baseOffset );
|
||||||
ULONG getModuleCheckSum( ULONG64 baseOffset );
|
ULONG getModuleCheckSum( ULONG64 baseOffset );
|
||||||
|
|
||||||
//manage access to target memory
|
// ýòî íóæíî ñäåëàòü ïî-äðóãîìó!
|
||||||
ULONG64 addr64( ULONG64 offset );
|
std::string getSymbolByOffset( ULONG64 offset );
|
||||||
|
|
||||||
void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr = FALSE );
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "dbgengine.h"
|
#include "dbgengine.h"
|
||||||
|
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE )
|
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr )
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ namespace pykd {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
ULONG64 addr64( ULONG64 offset );
|
||||||
|
void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr = FALSE );
|
||||||
bool isVaValid( ULONG64 addr );
|
bool isVaValid( ULONG64 addr );
|
||||||
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
|
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ std::string DiaException::makeFullDesc(const std::string &desc, HRESULT hres)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SymbolPtr loadSymbolFile(const std::string &filePath)
|
SymbolPtr loadSymbolFile(const std::string &filePath, ULONGLONG loadBase )
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
DiaDataSourcePtr dataSource;
|
DiaDataSourcePtr dataSource;
|
||||||
@ -64,6 +64,10 @@ SymbolPtr loadSymbolFile(const std::string &filePath)
|
|||||||
if ( S_OK != hres )
|
if ( S_OK != hres )
|
||||||
throw DiaException("Call IDiaDataSource::openSession", hres);
|
throw DiaException("Call IDiaDataSource::openSession", hres);
|
||||||
|
|
||||||
|
hres = _session->put_loadAddress(loadBase);
|
||||||
|
if (S_OK != hres)
|
||||||
|
throw DiaException("Call IDiaSession::put_loadAddress", hres);
|
||||||
|
|
||||||
DiaSymbolPtr _globalScope;
|
DiaSymbolPtr _globalScope;
|
||||||
hres = _session->get_globalScope(&_globalScope);
|
hres = _session->get_globalScope(&_globalScope);
|
||||||
if ( S_OK != hres )
|
if ( S_OK != hres )
|
||||||
@ -368,7 +372,6 @@ bool DiaSymbol::isVirtualBaseClass()
|
|||||||
// return !!callSymbol(get_indirectVirtualBaseClass);
|
// return !!callSymbol(get_indirectVirtualBaseClass);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}; // pykd nemaspace end
|
}; // pykd nemaspace end
|
||||||
|
|
||||||
|
@ -154,6 +154,8 @@ public:
|
|||||||
|
|
||||||
//ULONG getSection();
|
//ULONG getSection();
|
||||||
|
|
||||||
|
void setLoadAddress( ULONGLONG baseAddress );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef std::pair<ULONG, const char *> ValueNameEntry;
|
typedef std::pair<ULONG, const char *> ValueNameEntry;
|
||||||
|
|
||||||
|
537
pykd/module.cpp
537
pykd/module.cpp
@ -2,6 +2,7 @@
|
|||||||
#include "dbgengine.h"
|
#include "dbgengine.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
|
#include "vardata.h"
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ SymbolPtr& Module::getSymScope()
|
|||||||
if ( m_symfile.empty() )
|
if ( m_symfile.empty() )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
m_symScope = loadSymbolFile( m_symfile );
|
m_symScope = loadSymbolFile( m_symfile, m_base );
|
||||||
|
|
||||||
} while( false );
|
} while( false );
|
||||||
|
|
||||||
@ -109,450 +110,106 @@ std::string Module::print()
|
|||||||
sstr << "Start: " << std::hex << m_base << " End: " << getEnd() << " Size: " << m_size << std::endl;
|
sstr << "Start: " << std::hex << m_base << " End: " << getEnd() << " Size: " << m_size << std::endl;
|
||||||
sstr << "Image: " << m_imageName << std::endl;
|
sstr << "Image: " << m_imageName << std::endl;
|
||||||
sstr << "Symnol: " << m_symfile << std::endl;
|
sstr << "Symnol: " << m_symfile << std::endl;
|
||||||
//sstr << "Timestamp: " << m_timeDataStamp << std::endl;
|
sstr << "Timestamp: " << m_timeDataStamp << std::endl;
|
||||||
//sstr << "Check Sum: " << m_checkSum << std::endl;
|
sstr << "Check Sum: " << m_checkSum << std::endl;
|
||||||
|
|
||||||
return sstr.str();
|
return sstr.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypedVarPtr
|
||||||
|
Module::getTypedVarByAddr( ULONG64 offset )
|
||||||
|
{
|
||||||
|
offset = addr64(offset);
|
||||||
|
|
||||||
|
if ( offset < m_base || offset > getEnd() )
|
||||||
|
throw DbgException( "address is out of the module space" );
|
||||||
|
|
||||||
|
std::string symName = getSymbolByOffset( offset );
|
||||||
|
|
||||||
|
return getTypedVarByName( symName );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypedVarPtr
|
||||||
|
Module::getTypedVarByName( const std::string &symName )
|
||||||
|
{
|
||||||
|
SymbolPtr symVar = getSymScope()->getChildByName( symName );
|
||||||
|
|
||||||
|
TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symVar->getType() );
|
||||||
|
|
||||||
|
if ( LocIsConstant != symVar->getLocType() )
|
||||||
|
{
|
||||||
|
ULONG64 offset = getSymbol( symName );
|
||||||
|
return TypedVar::getTypedVar(typeInfo, VarDataMemory::factory(offset) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return TypedVar::getTypedVar( typeInfo, VarDataConst::factory(symVar) );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//HRESULT hres;
|
||||||
|
|
||||||
|
//pyDia::SymbolPtr symVar = getSymScope()->getChildByName( symName );
|
||||||
|
|
||||||
|
//std::string fullName = m_name;
|
||||||
|
//fullName += '!';
|
||||||
|
//fullName += symName;
|
||||||
|
|
||||||
|
//ULONG64 offset;
|
||||||
|
|
||||||
|
//hres = m_symbols->GetOffsetByName( fullName.c_str(), &offset );
|
||||||
|
|
||||||
|
//TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symVar->getType() );
|
||||||
|
|
||||||
|
//if ( FAILED( hres ) )
|
||||||
|
//{
|
||||||
|
// if ( LocIsConstant == symVar->getLocType() )
|
||||||
|
// return TypedVar::getTypedVar( m_client, typeInfo, VarDataConst::factory(m_control, symVar) );
|
||||||
|
// throw DbgException("IDebugSymbols::GetOffsetByName failed" );
|
||||||
|
//}
|
||||||
|
|
||||||
|
//return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, offset) );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypedVarPtr
|
||||||
|
Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 offset )
|
||||||
|
{
|
||||||
|
TypeInfoPtr typeInfo = getTypeByName( typeName );
|
||||||
|
|
||||||
|
return TypedVar::getTypedVar(typeInfo, VarDataMemory::factory(offset) );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypedVarPtr Module::containingRecordByName( ULONG64 offset, const std::string &typeName, const std::string &fieldName )
|
||||||
|
{
|
||||||
|
TypeInfoPtr typeInfo = getTypeByName( typeName );
|
||||||
|
|
||||||
|
return containingRecordByType( offset, typeInfo, fieldName );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::list Module::getTypedVarArrayByTypeName( ULONG64 offset, const std::string &typeName, ULONG number )
|
||||||
|
{
|
||||||
|
return getTypedVarArrayByType( offset, getTypeByName( typeName ), number );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::list Module::getTypedVarListByTypeName( ULONG64 listHeadAddress, const std::string &typeName, const std::string &listEntryName )
|
||||||
|
{
|
||||||
|
return getTypedVarListByType( listHeadAddress, getTypeByName( typeName ), listEntryName );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}; // end of namespace pykd
|
}; // end of namespace pykd
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#include "module.h"
|
|
||||||
//#include "dbgclient.h"
|
|
||||||
//#include "dbgmem.h"
|
|
||||||
//
|
|
||||||
//namespace pykd {
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//ModulePtr Module::loadModuleByName( const std::string &moduleName ) {
|
|
||||||
// return g_dbgClient->loadModuleByName( moduleName );
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
//ModulePtr Module::loadModuleByOffset( ULONG64 offset ) {
|
|
||||||
// return g_dbgClient->loadModuleByOffset( offset );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//Module::Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, const std::string& moduleName )
|
|
||||||
// : DbgObject( client )
|
|
||||||
// , m_synSymbols(synSymbols)
|
|
||||||
//{
|
|
||||||
// HRESULT hres;
|
|
||||||
//
|
|
||||||
// m_name = moduleName;
|
|
||||||
//
|
|
||||||
// hres = m_symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &m_base );
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// throw DbgException( "IDebugSymbol::GetModuleByModuleName failed" );
|
|
||||||
//
|
|
||||||
// DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
|
|
||||||
// hres = m_symbols->GetModuleParameters( 1, &m_base, 0, &moduleParam );
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
|
|
||||||
//
|
|
||||||
// m_size = moduleParam.Size;
|
|
||||||
// m_timeDataStamp = moduleParam.TimeDateStamp;
|
|
||||||
// m_checkSum = moduleParam.Checksum;
|
|
||||||
//
|
|
||||||
// char imageName[0x100];
|
|
||||||
//
|
|
||||||
// hres = m_symbols->GetModuleNameString(
|
|
||||||
// DEBUG_MODNAME_IMAGE,
|
|
||||||
// DEBUG_ANY_ID,
|
|
||||||
// m_base,
|
|
||||||
// imageName,
|
|
||||||
// sizeof( imageName ),
|
|
||||||
// NULL );
|
|
||||||
//
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// throw DbgException( "IDebugSymbol::GetModuleNameString failed" );
|
|
||||||
//
|
|
||||||
// m_imageName = std::string( imageName );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//Module::Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, ULONG64 offset )
|
|
||||||
// : DbgObject( client )
|
|
||||||
// , m_synSymbols(synSymbols)
|
|
||||||
//{
|
|
||||||
// HRESULT hres;
|
|
||||||
//
|
|
||||||
// offset = addr64( offset );
|
|
||||||
//
|
|
||||||
// ULONG moduleIndex;
|
|
||||||
// hres = m_symbols->GetModuleByOffset( offset, 0, &moduleIndex, &m_base );
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// throw DbgException( "IDebugSymbol::GetModuleByOffset failed" );
|
|
||||||
//
|
|
||||||
// char moduleName[0x100];
|
|
||||||
//
|
|
||||||
// hres = m_symbols->GetModuleNameString(
|
|
||||||
// DEBUG_MODNAME_MODULE,
|
|
||||||
// moduleIndex,
|
|
||||||
// 0,
|
|
||||||
// moduleName,
|
|
||||||
// sizeof( moduleName ),
|
|
||||||
// NULL );
|
|
||||||
//
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// throw DbgException( "IDebugSymbol::GetModuleNameString failed" );
|
|
||||||
//
|
|
||||||
// m_name = std::string( moduleName );
|
|
||||||
//
|
|
||||||
// char imageName[0x100];
|
|
||||||
//
|
|
||||||
// hres = m_symbols->GetModuleNameString(
|
|
||||||
// DEBUG_MODNAME_IMAGE,
|
|
||||||
// DEBUG_ANY_ID,
|
|
||||||
// m_base,
|
|
||||||
// imageName,
|
|
||||||
// sizeof( imageName ),
|
|
||||||
// NULL );
|
|
||||||
//
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// throw DbgException( "IDebugSymbol::GetModuleNameString failed" );
|
|
||||||
//
|
|
||||||
// m_imageName = std::string( imageName );
|
|
||||||
//
|
|
||||||
// DEBUG_MODULE_PARAMETERS moduleParam = { 0 };
|
|
||||||
// hres = m_symbols->GetModuleParameters( 1, &m_base, 0, &moduleParam );
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// throw DbgException( "IDebugSymbol::GetModuleParameters failed" );
|
|
||||||
//
|
|
||||||
// m_size = moduleParam.Size;
|
|
||||||
// m_timeDataStamp = moduleParam.TimeDateStamp;
|
|
||||||
// m_checkSum = moduleParam.Checksum;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//std::string
|
|
||||||
//Module::getPdbName()
|
|
||||||
//{
|
|
||||||
// HRESULT hres;
|
|
||||||
//
|
|
||||||
// IMAGEHLP_MODULEW64 moduleInfo = {};
|
|
||||||
//
|
|
||||||
// hres = m_advanced->GetSymbolInformation(
|
|
||||||
// DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
|
|
||||||
// m_base,
|
|
||||||
// 0,
|
|
||||||
// &moduleInfo,
|
|
||||||
// sizeof(moduleInfo),
|
|
||||||
// NULL,
|
|
||||||
// NULL,
|
|
||||||
// 0,
|
|
||||||
// NULL );
|
|
||||||
//
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
|
|
||||||
//
|
|
||||||
// if (!*moduleInfo.LoadedPdbName)
|
|
||||||
// {
|
|
||||||
// reloadSymbolsImpl();
|
|
||||||
//
|
|
||||||
// hres = m_advanced->GetSymbolInformation(
|
|
||||||
// DEBUG_SYMINFO_IMAGEHLP_MODULEW64,
|
|
||||||
// m_base,
|
|
||||||
// 0,
|
|
||||||
// &moduleInfo,
|
|
||||||
// sizeof(moduleInfo),
|
|
||||||
// NULL,
|
|
||||||
// NULL,
|
|
||||||
// 0,
|
|
||||||
// NULL );
|
|
||||||
//
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// throw DbgException( "IDebugAdvanced2::GetSymbolInformation failed" );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// char pdbName[ 256 ];
|
|
||||||
// WideCharToMultiByte( CP_ACP, 0, moduleInfo.LoadedPdbName, 256, pdbName, 256, NULL, NULL );
|
|
||||||
//
|
|
||||||
// return std::string( pdbName );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//void
|
|
||||||
//Module::reloadSymbolsImpl()
|
|
||||||
//{
|
|
||||||
// HRESULT hres;
|
|
||||||
//
|
|
||||||
// std::string param = "/f ";
|
|
||||||
// param += m_imageName;
|
|
||||||
//
|
|
||||||
// hres = m_symbols->Reload( param.c_str() );
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// throw DbgException("IDebugSymbols::Reload failed" );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//void
|
|
||||||
//Module::reloadSymbols()
|
|
||||||
//{
|
|
||||||
// reloadSymbolsImpl();
|
|
||||||
//
|
|
||||||
// m_dia.reset();
|
|
||||||
// m_dia = pyDia::GlobalScope::loadPdb( getPdbName() );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//TypedVarPtr
|
|
||||||
//Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
|
|
||||||
//{
|
|
||||||
// return TypedVar::getTypedVar( m_client, getTypeByName(typeName), VarDataMemory::factory(m_dataSpaces, addr) );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//TypedVarPtr
|
|
||||||
//Module::getTypedVarByType( const TypeInfoPtr &typeInfo, ULONG64 addr )
|
|
||||||
//{
|
|
||||||
// return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, addr) );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//ULONG64
|
|
||||||
//Module::getSymbolSize( const std::string &symName )
|
|
||||||
//{
|
|
||||||
// try {
|
|
||||||
//
|
|
||||||
// pyDia::SymbolPtr symVar = getDia()->getChildByName( symName );
|
|
||||||
//
|
|
||||||
// if ( symVar->getSymTag() == SymTagData )
|
|
||||||
// return symVar->getSize();
|
|
||||||
//
|
|
||||||
// } catch( const SymbolException& )
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return getTypeByName(symName)->getSize();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//TypedVarPtr
|
|
||||||
//Module::getTypedVarByName( const std::string &symName )
|
|
||||||
//{
|
|
||||||
// HRESULT hres;
|
|
||||||
//
|
|
||||||
// pyDia::SymbolPtr symVar = getDia()->getChildByName( symName );
|
|
||||||
//
|
|
||||||
// std::string fullName = m_name;
|
|
||||||
// fullName += '!';
|
|
||||||
// fullName += symName;
|
|
||||||
//
|
|
||||||
// ULONG64 offset;
|
|
||||||
//
|
|
||||||
// hres = m_symbols->GetOffsetByName( fullName.c_str(), &offset );
|
|
||||||
//
|
|
||||||
// TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symVar->getType() );
|
|
||||||
//
|
|
||||||
// if ( FAILED( hres ) )
|
|
||||||
// {
|
|
||||||
// if ( LocIsConstant == symVar->getLocType() )
|
|
||||||
// return TypedVar::getTypedVar( m_client, typeInfo, VarDataConst::factory(m_control, symVar) );
|
|
||||||
// throw DbgException("IDebugSymbols::GetOffsetByName failed" );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, offset) );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//TypedVarPtr
|
|
||||||
//Module::getTypedVarByAddr( ULONG64 addr )
|
|
||||||
//{
|
|
||||||
// HRESULT hres;
|
|
||||||
//
|
|
||||||
// addr = addr64(addr);
|
|
||||||
//
|
|
||||||
// if ( addr < m_base || addr > getEnd() )
|
|
||||||
// throw DbgException( "address is out of the module space" );
|
|
||||||
//
|
|
||||||
// char nameBuf[0x100];
|
|
||||||
//
|
|
||||||
// hres =
|
|
||||||
// m_symbols->GetNameByOffset(
|
|
||||||
// addr,
|
|
||||||
// nameBuf,
|
|
||||||
// sizeof(nameBuf),
|
|
||||||
// NULL,
|
|
||||||
// NULL );
|
|
||||||
//
|
|
||||||
// std::string fullName( nameBuf );
|
|
||||||
//
|
|
||||||
// size_t symPos = fullName.find ( '!' ) + 1;
|
|
||||||
//
|
|
||||||
// std::string symbolName;
|
|
||||||
// symbolName.assign( fullName, symPos, fullName.length() - symPos );
|
|
||||||
//
|
|
||||||
// if ( FAILED(hres) )
|
|
||||||
// throw DbgException( "failed IDebugSymbols::GetNameByOffset" );
|
|
||||||
//
|
|
||||||
// return getTypedVarByName( symbolName );
|
|
||||||
//
|
|
||||||
// //LONG displacement;
|
|
||||||
// //pyDia::SymbolPtr diaSym =
|
|
||||||
// // getDia()->findByRvaImpl((ULONG)(addr - m_base), SymTagData, displacement);
|
|
||||||
// //if (displacement)
|
|
||||||
// // throw DbgException( "not exactly match by RVA" );
|
|
||||||
//
|
|
||||||
// //return TypedVar::getTypedVar( m_client, TypeInfo::getTypeInfo( diaSym->getType() ), addr );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//ULONG Module::getRvaByName(const std::string &symName)
|
|
||||||
//{
|
|
||||||
// HRESULT hres;
|
|
||||||
// ULONG64 offset;
|
|
||||||
//
|
|
||||||
// hres = m_symbols->GetOffsetByName( symName.c_str(), &offset );
|
|
||||||
// if ( SUCCEEDED(hres) )
|
|
||||||
// return (ULONG)(offset - m_base);
|
|
||||||
//
|
|
||||||
// return (ULONG)m_synSymbols->getRvaByName(m_timeDataStamp, m_checkSum, symName);
|
|
||||||
//
|
|
||||||
// //try {
|
|
||||||
// // pyDia::SymbolPtr sym = getDia()->getChildByName( symName );
|
|
||||||
// // return sym->getRva();
|
|
||||||
// //}
|
|
||||||
// //catch (const pyDia::Exception &) {
|
|
||||||
// //}
|
|
||||||
// //return (ULONG)m_synSymbols->getRvaByName(m_timeDataStamp, m_checkSumm, symName);
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//TypedVarPtr Module::containingRecordByName( ULONG64 address, const std::string &typeName, const std::string &fieldName )
|
|
||||||
//{
|
|
||||||
// address = addr64(address);
|
|
||||||
//
|
|
||||||
// TypeInfoPtr typeInfo = getTypeByName( typeName );
|
|
||||||
//
|
|
||||||
// VarDataPtr varData =
|
|
||||||
// VarDataMemory::factory(
|
|
||||||
// m_dataSpaces,
|
|
||||||
// address - typeInfo->getFieldOffsetByNameRecirsive( fieldName )
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// return TypedVar::getTypedVar( m_client, typeInfo, varData );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//TypedVarPtr Module::containingRecordByType( ULONG64 address, const TypeInfoPtr &typeInfo, const std::string &fieldName )
|
|
||||||
//{
|
|
||||||
// address = addr64(address);
|
|
||||||
//
|
|
||||||
// VarDataPtr varData =
|
|
||||||
// VarDataMemory::factory(
|
|
||||||
// m_dataSpaces,
|
|
||||||
// address - typeInfo->getFieldOffsetByNameRecirsive( fieldName )
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// return TypedVar::getTypedVar( m_client, typeInfo, varData );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//python::list Module::getTypedVarListByTypeName( ULONG64 listHeadAddress, const std::string &typeName, const std::string &listEntryName )
|
|
||||||
//{
|
|
||||||
// return getTypedVarListByType( listHeadAddress, getTypeByName( typeName ), listEntryName );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//python::list Module::getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &typeInfo, const std::string &listEntryName )
|
|
||||||
//{
|
|
||||||
// python::list lst;
|
|
||||||
//
|
|
||||||
// listHeadAddress = addr64( listHeadAddress );
|
|
||||||
//
|
|
||||||
// ULONG64 entryAddress = 0;
|
|
||||||
//
|
|
||||||
// TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
|
|
||||||
//
|
|
||||||
// if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) )
|
|
||||||
// {
|
|
||||||
// for( entryAddress = ptrPtr( listHeadAddress, m_dataSpaces ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + typeInfo->getFieldOffsetByNameRecirsive(listEntryName) ) )
|
|
||||||
// lst.append( getTypedVarByType( typeInfo, entryAddress ) );
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// for( entryAddress = ptrPtr( listHeadAddress, m_dataSpaces ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) )
|
|
||||||
// lst.append( containingRecordByType( entryAddress, typeInfo, listEntryName ) );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return lst;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//python::list Module::getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number )
|
|
||||||
//{
|
|
||||||
// return getTypedVarArrayByType( addr, getTypeByName( typeName ), number );
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//python::list Module::getTypedVarArrayByType( ULONG64 address, const TypeInfoPtr &typeInfo, ULONG number )
|
|
||||||
//{
|
|
||||||
// address = addr64(address);
|
|
||||||
//
|
|
||||||
// python::list lst;
|
|
||||||
//
|
|
||||||
// for( ULONG i = 0; i < number; ++i )
|
|
||||||
// lst.append( getTypedVarByType( typeInfo, address + i * typeInfo->getSize() ) );
|
|
||||||
//
|
|
||||||
// return lst;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//std::string Module::print()
|
|
||||||
//{
|
|
||||||
// std::stringstream sstr;
|
|
||||||
//
|
|
||||||
// sstr << "Module: " << m_name << std::endl;
|
|
||||||
// sstr << "Start: " << std::hex << m_base << " End: " << getEnd() << " Size: " << m_size << std::endl;
|
|
||||||
// sstr << "Image: " << m_imageName << std::endl;
|
|
||||||
// sstr << "Pdb: " << getPdbName() << std::endl;
|
|
||||||
// sstr << "Timestamp: " << m_timeDataStamp << std::endl;
|
|
||||||
// sstr << "Check Sum: " << m_checkSum << std::endl;
|
|
||||||
//
|
|
||||||
// return sstr.str();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//}; // end of namespace pykd
|
|
||||||
//
|
|
||||||
|
166
pykd/module.h
166
pykd/module.h
@ -3,6 +3,7 @@
|
|||||||
#include "intbase.h"
|
#include "intbase.h"
|
||||||
#include "symengine.h"
|
#include "symengine.h"
|
||||||
#include "typeinfo.h"
|
#include "typeinfo.h"
|
||||||
|
#include "typedvar.h"
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
@ -78,6 +79,18 @@ public:
|
|||||||
return TypeInfo::getTypeInfo( boost::static_pointer_cast<Symbol>( getSymScope() ), typeName);
|
return TypeInfo::getTypeInfo( boost::static_pointer_cast<Symbol>( getSymScope() ), typeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypedVarPtr getTypedVarByAddr( ULONG64 addr );
|
||||||
|
|
||||||
|
TypedVarPtr getTypedVarByName( const std::string &symName );
|
||||||
|
|
||||||
|
TypedVarPtr getTypedVarByTypeName( const std::string &typeName, ULONG64 addr );
|
||||||
|
|
||||||
|
python::list getTypedVarListByTypeName( ULONG64 listHeadAddres, const std::string &typeName, const std::string &listEntryName );
|
||||||
|
|
||||||
|
python::list getTypedVarArrayByTypeName( ULONG64 offset, const std::string &typeName, ULONG number );
|
||||||
|
|
||||||
|
TypedVarPtr containingRecordByName( ULONG64 offset, const std::string &typeName, const std::string &fieldName );
|
||||||
|
|
||||||
ULONG64 getSymbolSize( const std::string &symName );
|
ULONG64 getSymbolSize( const std::string &symName );
|
||||||
|
|
||||||
std::string print();
|
std::string print();
|
||||||
@ -107,156 +120,3 @@ private:
|
|||||||
|
|
||||||
}; // end pykd namespace
|
}; // end pykd namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//#include <string>
|
|
||||||
//
|
|
||||||
//#include "dbgobj.h"
|
|
||||||
//#include "diawrapper.h"
|
|
||||||
//#include "typeinfo.h"
|
|
||||||
//#include "typedvar.h"
|
|
||||||
//#include "synsymbol.h"
|
|
||||||
//
|
|
||||||
//namespace pykd {
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//class Module;
|
|
||||||
//typedef boost::shared_ptr<Module> ModulePtr;
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//class Module : public intBase, private DbgObject {
|
|
||||||
//
|
|
||||||
//public:
|
|
||||||
//
|
|
||||||
// static
|
|
||||||
// ModulePtr loadModuleByName( const std::string &name );
|
|
||||||
//
|
|
||||||
// static
|
|
||||||
// ModulePtr loadModuleByOffset( ULONG64 offset );
|
|
||||||
//
|
|
||||||
//public:
|
|
||||||
//
|
|
||||||
// Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, const std::string& moduleName );
|
|
||||||
//
|
|
||||||
// Module( IDebugClient4 *client, SynSymbolsPtr synSymbols, ULONG64 offset );
|
|
||||||
//
|
|
||||||
// std::string getName() {
|
|
||||||
// return m_name;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// std::string getImageName() {
|
|
||||||
// return m_imageName;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG64 getBase() const {
|
|
||||||
// return m_base;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG64 getEnd() const {
|
|
||||||
// return m_base + m_size;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG getSize() const {
|
|
||||||
// return m_size;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// std::string
|
|
||||||
// getPdbName();
|
|
||||||
//
|
|
||||||
// void
|
|
||||||
// reloadSymbols();
|
|
||||||
//
|
|
||||||
// ULONG64
|
|
||||||
// getSymbol( const std::string &symbolname ) {
|
|
||||||
// return m_base + getRvaByName(symbolname);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG
|
|
||||||
// getSymbolRva( const std::string &symbolname ) {
|
|
||||||
// return getRvaByName(symbolname);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// TypeInfoPtr getTypeByName( const std::string &typeName ) {
|
|
||||||
// return TypeInfo::getTypeInfo( boost::static_pointer_cast<pyDia::Symbol>( getDia() ), typeName);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// TypedVarPtr getTypedVarByTypeName( const std::string &typeName, ULONG64 addr );
|
|
||||||
//
|
|
||||||
// TypedVarPtr getTypedVarByType( const TypeInfoPtr &typeInfo, ULONG64 addr );
|
|
||||||
//
|
|
||||||
// TypedVarPtr getTypedVarByAddr( ULONG64 addr );
|
|
||||||
//
|
|
||||||
// TypedVarPtr getTypedVarByName( const std::string &symName );
|
|
||||||
//
|
|
||||||
// TypedVarPtr containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName );
|
|
||||||
//
|
|
||||||
// TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName );
|
|
||||||
//
|
|
||||||
// python::list getTypedVarListByTypeName( ULONG64 listHeadAddres, const std::string &typeName, const std::string &listEntryName );
|
|
||||||
//
|
|
||||||
// python::list getTypedVarListByType( ULONG64 listHeadAddres, const TypeInfoPtr &typeInfo, const std::string &listEntryName );
|
|
||||||
//
|
|
||||||
// python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number );
|
|
||||||
//
|
|
||||||
// python::list getTypedVarArrayByType( ULONG64 addr, const TypeInfoPtr &typeInfo, ULONG number );
|
|
||||||
//
|
|
||||||
// ULONG64 getSymbolSize( const std::string &symName );
|
|
||||||
//
|
|
||||||
// pyDia::GlobalScopePtr& getDia() {
|
|
||||||
// if (!m_dia)
|
|
||||||
// {
|
|
||||||
// m_dia = pyDia::GlobalScope::loadPdb( getPdbName() );
|
|
||||||
// if ( m_dia )
|
|
||||||
// {
|
|
||||||
// m_dia->setLoadAddress( m_base );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return m_dia;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG getCheckSum() const {
|
|
||||||
// return m_checkSum;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ULONG getTimeDataStamp() const {
|
|
||||||
// return m_timeDataStamp;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// std::string print();
|
|
||||||
//
|
|
||||||
//private:
|
|
||||||
//
|
|
||||||
// void
|
|
||||||
// reloadSymbolsImpl();
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// ULONG getRvaByName(const std::string &symName);
|
|
||||||
//
|
|
||||||
// BaseTypeVariant getValue() {
|
|
||||||
// return BaseTypeVariant(m_base);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// std::string m_name;
|
|
||||||
// std::string m_imageName;
|
|
||||||
// ULONG64 m_base;
|
|
||||||
// ULONG m_size;
|
|
||||||
//
|
|
||||||
// pyDia::GlobalScopePtr m_dia;
|
|
||||||
//
|
|
||||||
// ULONG m_timeDataStamp;
|
|
||||||
// ULONG m_checkSum;
|
|
||||||
// SynSymbolsPtr m_synSymbols;
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
//}; // end pykd namespace
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -409,6 +409,10 @@
|
|||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\typedvar.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\typeinfo.cpp"
|
RelativePath=".\typeinfo.cpp"
|
||||||
>
|
>
|
||||||
@ -417,6 +421,10 @@
|
|||||||
RelativePath=".\udtutils.cpp"
|
RelativePath=".\udtutils.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\vardata.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
@ -459,6 +467,10 @@
|
|||||||
RelativePath=".\symengine.h"
|
RelativePath=".\symengine.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\typedvar.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\typeinfo.h"
|
RelativePath=".\typeinfo.h"
|
||||||
>
|
>
|
||||||
@ -467,6 +479,10 @@
|
|||||||
RelativePath=".\udtutils.h"
|
RelativePath=".\udtutils.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\vardata.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Resource Files"
|
Name="Resource Files"
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
#include "dbgmem.h"
|
#include "dbgmem.h"
|
||||||
#include "typeinfo.h"
|
#include "typeinfo.h"
|
||||||
|
#include "typedvar.h"
|
||||||
|
|
||||||
using namespace pykd;
|
using namespace pykd;
|
||||||
|
|
||||||
@ -127,6 +128,20 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
// typed and vaiables
|
// typed and vaiables
|
||||||
python::def( "sizeof", &TypeInfo::getSymbolSize,
|
python::def( "sizeof", &TypeInfo::getSymbolSize,
|
||||||
"Return a size of the type or variable" );
|
"Return a size of the type or variable" );
|
||||||
|
python::def("typedVarList", &getTypedVarListByTypeName,
|
||||||
|
"Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" );
|
||||||
|
python::def("typedVarList", &getTypedVarListByType,
|
||||||
|
"Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" );
|
||||||
|
python::def("typedVarArray", &getTypedVarArrayByTypeName,
|
||||||
|
"Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" );
|
||||||
|
python::def("typedVarArray", &getTypedVarArrayByType,
|
||||||
|
"Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" );
|
||||||
|
python::def("containingRecord", &containingRecordByName,
|
||||||
|
"Return instance of the typedVar class. It's value are loaded from the target memory."
|
||||||
|
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" );
|
||||||
|
python::def("containingRecord", &containingRecordByType,
|
||||||
|
"Return instance of the typedVar class. It's value are loaded from the target memory."
|
||||||
|
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" );
|
||||||
|
|
||||||
python::class_<intBase>( "intBase", "intBase", python::no_init )
|
python::class_<intBase>( "intBase", "intBase", python::no_init )
|
||||||
.def( python::init<python::object&>() )
|
.def( python::init<python::object&>() )
|
||||||
@ -193,32 +208,23 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
"Return offset of the symbol" )
|
"Return offset of the symbol" )
|
||||||
.def("rva", &Module::getSymbolRva,
|
.def("rva", &Module::getSymbolRva,
|
||||||
"Return rva of the symbol" )
|
"Return rva of the symbol" )
|
||||||
//.def( "sizeof", &Module::getSymbolSize,
|
.def( "sizeof", &Module::getSymbolSize,
|
||||||
// "Return a size of the type or variable" )
|
"Return a size of the type or variable" )
|
||||||
.def("type", &Module::getTypeByName,
|
.def("type", &Module::getTypeByName,
|
||||||
"Return typeInfo class by type name" )
|
"Return typeInfo class by type name" )
|
||||||
//.def("typedVar", &Module::getTypedVarByAddr,
|
.def("typedVar", &Module::getTypedVarByAddr,
|
||||||
// "Return a typedVar class instance" )
|
"Return a typedVar class instance" )
|
||||||
//.def("typedVar",&Module::getTypedVarByName,
|
.def("typedVar",&Module::getTypedVarByName,
|
||||||
// "Return a typedVar class instance" )
|
"Return a typedVar class instance" )
|
||||||
//.def("typedVar",&Module::getTypedVarByType,
|
.def("typedVar",&Module::getTypedVarByTypeName,
|
||||||
// "Return a typedVar class instance" )
|
"Return a typedVar class instance" )
|
||||||
//.def("typedVar",&Module::getTypedVarByTypeName,
|
.def("typedVarList", &Module::getTypedVarListByTypeName,
|
||||||
// "Return a typedVar class instance" )
|
"Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" )
|
||||||
//.def("typedVarList", &Module::getTypedVarListByTypeName,
|
.def("typedVarArray", &Module::getTypedVarArrayByTypeName,
|
||||||
// "Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" )
|
"Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" )
|
||||||
//.def("typedVarList", &Module::getTypedVarListByType,
|
.def("containingRecord", &Module::containingRecordByName,
|
||||||
// "Return a list of the typedVar class instances. Each item represents an item of the linked list in the target memory" )
|
"Return instance of the typedVar class. It's value are loaded from the target memory."
|
||||||
//.def("typedVarArray", &Module::getTypedVarArrayByTypeName,
|
"The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )
|
||||||
// "Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" )
|
|
||||||
//.def("typedVarArray", &Module::getTypedVarArrayByType,
|
|
||||||
// "Return a list of the typedVar class instances. Each item represents an item of the counted array in the target memory" )
|
|
||||||
//.def("containingRecord", &Module::containingRecordByName,
|
|
||||||
// "Return instance of the typedVar class. It's value are loaded from the target memory."
|
|
||||||
// "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )
|
|
||||||
//.def("containingRecord", &Module::containingRecordByType,
|
|
||||||
// "Return instance of the typedVar class. It's value are loaded from the target memory."
|
|
||||||
// "The start address is calculated by the same method as the standard macro CONTAINING_RECORD does" )
|
|
||||||
.def("checksum",&Module::getCheckSum,
|
.def("checksum",&Module::getCheckSum,
|
||||||
"Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" )
|
"Return a image file checksum: IMAGE_OPTIONAL_HEADER.CheckSum" )
|
||||||
.def("timestamp",&Module::getTimeDataStamp,
|
.def("timestamp",&Module::getTimeDataStamp,
|
||||||
@ -243,6 +249,34 @@ BOOST_PYTHON_MODULE( pykd )
|
|||||||
.def("__len__", &TypeInfo::getElementCount )
|
.def("__len__", &TypeInfo::getElementCount )
|
||||||
.def("__getitem__", &TypeInfo::getElementByIndex );
|
.def("__getitem__", &TypeInfo::getElementByIndex );
|
||||||
|
|
||||||
|
python::class_<TypedVar, TypedVarPtr, python::bases<intBase>, boost::noncopyable >("typedVar",
|
||||||
|
"Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance", python::no_init )
|
||||||
|
.def("__init__", python::make_constructor(TypedVar::getTypedVarByName) )
|
||||||
|
.def("__init__", python::make_constructor(TypedVar::getTypedVarByTypeName) )
|
||||||
|
.def("__init__", python::make_constructor(TypedVar::getTypedVarByTypeInfo) )
|
||||||
|
.def("getAddress", &TypedVar::getAddress,
|
||||||
|
"Return virtual address" )
|
||||||
|
.def("sizeof", &TypedVar::getSize,
|
||||||
|
"Return size of a variable in the target memory" )
|
||||||
|
.def("fieldOffset", &TypedVar::getFieldOffsetByNameRecirsive,
|
||||||
|
"Return target field offset" )
|
||||||
|
.def("field", &TypedVar::getField,
|
||||||
|
"Return field of structure as an object attribute" )
|
||||||
|
.def( "dataKind", &TypedVar::getDataKind,
|
||||||
|
"Retrieves the variable classification of a data: DataIsXxx")
|
||||||
|
.def("deref", &TypedVar::deref,
|
||||||
|
"Return value by pointer" )
|
||||||
|
.def("type", &TypedVar::getType,
|
||||||
|
"Return typeInfo instance" )
|
||||||
|
.def("__getattr__", &TypedVar::getField,
|
||||||
|
"Return field of structure as an object attribute" )
|
||||||
|
.def( "__str__", &TypedVar::print )
|
||||||
|
.def("__len__", &TypedVar::getElementCount )
|
||||||
|
.def("__getitem__", &TypedVar::getElementByIndex )
|
||||||
|
.def("__getitem__", &TypedVar::getElementByIndexPtr );
|
||||||
|
|
||||||
|
// wrapper for standart python exceptions
|
||||||
|
python::register_exception_translator<PyException>( &PyException::exceptionTranslate );
|
||||||
|
|
||||||
pykd::exception<DbgException>( "BaseException", "Pykd base exception class" );
|
pykd::exception<DbgException>( "BaseException", "Pykd base exception class" );
|
||||||
pykd::exception<MemoryException,DbgException>( "MemoryException", "Target memory access exception class" );
|
pykd::exception<MemoryException,DbgException>( "MemoryException", "Target memory access exception class" );
|
||||||
|
@ -110,7 +110,6 @@ class Symbol {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
virtual SymbolPtrList findChildren( ULONG symTag, const std::string &name = "", bool caseSensitive = FALSE ) = 0;
|
virtual SymbolPtrList findChildren( ULONG symTag, const std::string &name = "", bool caseSensitive = FALSE ) = 0;
|
||||||
virtual ULONG getBaseType() = 0;
|
virtual ULONG getBaseType() = 0;
|
||||||
virtual ULONG getBitPosition() = 0;
|
virtual ULONG getBitPosition() = 0;
|
||||||
@ -140,7 +139,7 @@ public:
|
|||||||
|
|
||||||
std::string getBasicTypeName( ULONG basicType );
|
std::string getBasicTypeName( ULONG basicType );
|
||||||
|
|
||||||
SymbolPtr loadSymbolFile(const std::string &filePath);
|
SymbolPtr loadSymbolFile(const std::string &filePath, ULONGLONG loadBase = 0);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -3,50 +3,50 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
#include "typedvar.h"
|
#include "typedvar.h"
|
||||||
#include "dbgclient.h"
|
#include "module.h"
|
||||||
#include "dbgmem.h"
|
#include "dbgmem.h"
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TypedVarPtr TypedVar::getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
|
TypedVarPtr TypedVar::getTypedVar( const TypeInfoPtr& typeInfo, VarDataPtr varData )
|
||||||
{
|
{
|
||||||
TypedVarPtr tv;
|
TypedVarPtr tv;
|
||||||
|
|
||||||
if ( typeInfo->isBasicType() )
|
if ( typeInfo->isBasicType() )
|
||||||
{
|
{
|
||||||
tv.reset( new BasicTypedVar( client, typeInfo, varData) );
|
tv.reset( new BasicTypedVar( typeInfo, varData) );
|
||||||
return tv;
|
return tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( typeInfo->isPointer() )
|
if ( typeInfo->isPointer() )
|
||||||
{
|
{
|
||||||
tv.reset( new PtrTypedVar( client, typeInfo, varData ) );
|
tv.reset( new PtrTypedVar( typeInfo, varData ) );
|
||||||
return tv;
|
return tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( typeInfo->isArray() )
|
if ( typeInfo->isArray() )
|
||||||
{
|
{
|
||||||
tv.reset( new ArrayTypedVar( client, typeInfo, varData ) );
|
tv.reset( new ArrayTypedVar( typeInfo, varData ) );
|
||||||
return tv;
|
return tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( typeInfo->isUserDefined() )
|
if ( typeInfo->isUserDefined() )
|
||||||
{
|
{
|
||||||
tv.reset( new UdtTypedVar( client, typeInfo, varData ) );
|
tv.reset( new UdtTypedVar( typeInfo, varData ) );
|
||||||
return tv;
|
return tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( typeInfo->isBitField() )
|
if ( typeInfo->isBitField() )
|
||||||
{
|
{
|
||||||
tv.reset( new BitFieldVar( client, typeInfo, varData ) );
|
tv.reset( new BitFieldVar( typeInfo, varData ) );
|
||||||
return tv;
|
return tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( typeInfo->isEnum() )
|
if ( typeInfo->isEnum() )
|
||||||
{
|
{
|
||||||
tv.reset( new EnumTypedVar( client, typeInfo, varData ) );
|
tv.reset( new EnumTypedVar( typeInfo, varData ) );
|
||||||
return tv;
|
return tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,23 +59,42 @@ TypedVarPtr TypedVar::getTypedVar( IDebugClient4 *client, const TypeInfoPtr& t
|
|||||||
|
|
||||||
TypedVarPtr TypedVar::getTypedVarByName( const std::string &varName )
|
TypedVarPtr TypedVar::getTypedVarByName( const std::string &varName )
|
||||||
{
|
{
|
||||||
return g_dbgClient->getTypedVarByName( varName );
|
std::string moduleName;
|
||||||
}
|
std::string symName;
|
||||||
|
|
||||||
TypedVarPtr TypedVar::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
|
splitSymName( varName, moduleName, symName );
|
||||||
{
|
|
||||||
return g_dbgClient->getTypedVarByTypeName( typeName, addr );
|
|
||||||
}
|
|
||||||
|
|
||||||
TypedVarPtr TypedVar::getTypedVarByTypeInfo( const TypeInfoPtr &typeInfo, ULONG64 addr )
|
ModulePtr module = Module::loadModuleByName( moduleName );
|
||||||
{
|
|
||||||
return g_dbgClient->getTypedVarByTypeInfo( typeInfo, addr );
|
return module->getTypedVarByName( symName );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ) :
|
TypedVarPtr TypedVar::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
|
||||||
DbgObject( client ),
|
{
|
||||||
|
addr = addr64( addr );
|
||||||
|
|
||||||
|
std::string moduleName;
|
||||||
|
std::string symName;
|
||||||
|
|
||||||
|
splitSymName( typeName, moduleName, symName );
|
||||||
|
|
||||||
|
ModulePtr module = Module::loadModuleByName( moduleName );
|
||||||
|
|
||||||
|
return module->getTypedVarByTypeName( symName, addr );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypedVarPtr TypedVar::getTypedVarByTypeInfo( const TypeInfoPtr &typeInfo, ULONG64 addr )
|
||||||
|
{
|
||||||
|
return getTypedVar( typeInfo, VarDataMemory::factory(addr) );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypedVar::TypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData ) :
|
||||||
m_typeInfo( typeInfo ),
|
m_typeInfo( typeInfo ),
|
||||||
m_varData( varData ),
|
m_varData( varData ),
|
||||||
m_dataKind( DataIsGlobal )
|
m_dataKind( DataIsGlobal )
|
||||||
@ -166,8 +185,8 @@ BaseTypeVariant PtrTypedVar::getValue()
|
|||||||
|
|
||||||
TypedVarPtr PtrTypedVar::deref()
|
TypedVarPtr PtrTypedVar::deref()
|
||||||
{
|
{
|
||||||
VarDataPtr varData = VarDataMemory::factory( m_dataSpaces, m_varData->readPtr() );
|
VarDataPtr varData = VarDataMemory::factory( m_varData->readPtr() );
|
||||||
return TypedVar::getTypedVar( m_client, m_typeInfo->deref(), varData );
|
return TypedVar::getTypedVar( m_typeInfo->deref(), varData );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -220,7 +239,7 @@ python::object ArrayTypedVar::getElementByIndex( ULONG index )
|
|||||||
|
|
||||||
TypeInfoPtr elementType = m_typeInfo->getElementType();
|
TypeInfoPtr elementType = m_typeInfo->getElementType();
|
||||||
|
|
||||||
return python::object( TypedVar::getTypedVar( m_client, elementType, m_varData->fork(elementType->getSize()*index) ) );
|
return python::object( TypedVar::getTypedVar( elementType, m_varData->fork(elementType->getSize()*index) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -235,7 +254,7 @@ UdtTypedVar::getField( const std::string &fieldName )
|
|||||||
if ( fieldType->getStaticOffset() == 0 )
|
if ( fieldType->getStaticOffset() == 0 )
|
||||||
throw ImplementException( __FILE__, __LINE__, "Fix ME");
|
throw ImplementException( __FILE__, __LINE__, "Fix ME");
|
||||||
|
|
||||||
return TypedVar::getTypedVar( m_client, fieldType, VarDataMemory::factory(m_dataSpaces, fieldType->getStaticOffset() ) );
|
return TypedVar::getTypedVar( fieldType, VarDataMemory::factory(fieldType->getStaticOffset() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG fieldOffset = 0;
|
ULONG fieldOffset = 0;
|
||||||
@ -247,7 +266,7 @@ UdtTypedVar::getField( const std::string &fieldName )
|
|||||||
fieldOffset += getVirtualBaseDisplacement( fieldType );
|
fieldOffset += getVirtualBaseDisplacement( fieldType );
|
||||||
}
|
}
|
||||||
|
|
||||||
return TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldOffset) );
|
return TypedVar::getTypedVar( fieldType, m_varData->fork(fieldOffset) );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -264,7 +283,7 @@ UdtTypedVar::getElementByIndex( ULONG index )
|
|||||||
|
|
||||||
return python::make_tuple(
|
return python::make_tuple(
|
||||||
m_typeInfo->getFieldNameByIndex(index),
|
m_typeInfo->getFieldNameByIndex(index),
|
||||||
TypedVar::getTypedVar( m_client, fieldType, VarDataMemory::factory(m_dataSpaces, fieldType->getStaticOffset() ) ) );
|
TypedVar::getTypedVar(fieldType, VarDataMemory::factory(fieldType->getStaticOffset() ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG fieldOffset = m_typeInfo->getFieldOffsetByIndex(index);
|
ULONG fieldOffset = m_typeInfo->getFieldOffsetByIndex(index);
|
||||||
@ -276,7 +295,7 @@ UdtTypedVar::getElementByIndex( ULONG index )
|
|||||||
|
|
||||||
return python::make_tuple(
|
return python::make_tuple(
|
||||||
m_typeInfo->getFieldNameByIndex(index),
|
m_typeInfo->getFieldNameByIndex(index),
|
||||||
TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldOffset) ) );
|
TypedVar::getTypedVar( fieldType, m_varData->fork(fieldOffset) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -288,7 +307,7 @@ LONG UdtTypedVar::getVirtualBaseDisplacement( TypeInfoPtr& typeInfo )
|
|||||||
|
|
||||||
ULONG64 vbtableOffset = m_varData->fork( virtualBasePtr )->readPtr();
|
ULONG64 vbtableOffset = m_varData->fork( virtualBasePtr )->readPtr();
|
||||||
|
|
||||||
VarDataPtr vbtable = VarDataMemory::factory(m_dataSpaces, vbtableOffset);
|
VarDataPtr vbtable = VarDataMemory::factory(vbtableOffset);
|
||||||
|
|
||||||
LONG displacement = 0;
|
LONG displacement = 0;
|
||||||
|
|
||||||
@ -313,7 +332,7 @@ std::string UdtTypedVar::print()
|
|||||||
if ( fieldType->isStaticMember() )
|
if ( fieldType->isStaticMember() )
|
||||||
{
|
{
|
||||||
if ( fieldType->getStaticOffset() != 0 )
|
if ( fieldType->getStaticOffset() != 0 )
|
||||||
fieldVar = TypedVar::getTypedVar( m_client, fieldType, VarDataMemory::factory(m_dataSpaces, fieldType->getStaticOffset() ) );
|
fieldVar = TypedVar::getTypedVar( fieldType, VarDataMemory::factory( fieldType->getStaticOffset() ) );
|
||||||
|
|
||||||
sstr << " =" << std::right << std::setw(10) << std::setfill('0') << std::hex << fieldType->getStaticOffset();
|
sstr << " =" << std::right << std::setw(10) << std::setfill('0') << std::hex << fieldType->getStaticOffset();
|
||||||
sstr << " " << std::left << std::setw(18) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':';
|
sstr << " " << std::left << std::setw(18) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':';
|
||||||
@ -327,7 +346,7 @@ std::string UdtTypedVar::print()
|
|||||||
fieldOffset += getVirtualBaseDisplacement( fieldType );
|
fieldOffset += getVirtualBaseDisplacement( fieldType );
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldVar = TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldOffset) );
|
fieldVar = TypedVar::getTypedVar( fieldType, m_varData->fork(fieldOffset) );
|
||||||
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldOffset;
|
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldOffset;
|
||||||
sstr << " " << std::left << std::setw(24) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':';
|
sstr << " " << std::left << std::setw(24) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':';
|
||||||
}
|
}
|
||||||
@ -446,4 +465,98 @@ std::string EnumTypedVar::printValue()
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypedVarPtr containingRecordByName( ULONG64 offset, const std::string &typeName, const std::string &fieldName )
|
||||||
|
{
|
||||||
|
std::string moduleName;
|
||||||
|
std::string symName;
|
||||||
|
|
||||||
|
splitSymName( typeName, moduleName, symName );
|
||||||
|
|
||||||
|
ModulePtr module = Module::loadModuleByName( moduleName );
|
||||||
|
|
||||||
|
return module->containingRecordByName( offset, symName, fieldName );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName )
|
||||||
|
{
|
||||||
|
addr = addr64(addr);
|
||||||
|
|
||||||
|
VarDataPtr varData = VarDataMemory::factory( addr - typeInfo->getFieldOffsetByNameRecirsive(fieldName) );
|
||||||
|
|
||||||
|
return TypedVar::getTypedVar( typeInfo, varData );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::list getTypedVarListByTypeName( ULONG64 listHeadAddress, const std::string &typeName, const std::string &listEntryName )
|
||||||
|
{
|
||||||
|
std::string moduleName;
|
||||||
|
std::string symName;
|
||||||
|
|
||||||
|
splitSymName( typeName, moduleName, symName );
|
||||||
|
|
||||||
|
ModulePtr module = Module::loadModuleByName( moduleName );
|
||||||
|
|
||||||
|
return module->getTypedVarListByTypeName( listHeadAddress, symName, listEntryName );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::list getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &typeInfo, const std::string &listEntryName )
|
||||||
|
{
|
||||||
|
python::list lst;
|
||||||
|
|
||||||
|
listHeadAddress = addr64( listHeadAddress );
|
||||||
|
|
||||||
|
ULONG64 entryAddress = 0;
|
||||||
|
|
||||||
|
TypeInfoPtr fieldTypeInfo = typeInfo->getField( listEntryName );
|
||||||
|
|
||||||
|
if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) )
|
||||||
|
{
|
||||||
|
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress + typeInfo->getFieldOffsetByNameRecirsive(listEntryName) ) )
|
||||||
|
lst.append( TypedVar::getTypedVarByTypeInfo( typeInfo, entryAddress ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( entryAddress = ptrPtr( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrPtr( entryAddress ) )
|
||||||
|
lst.append( containingRecordByType( entryAddress, typeInfo, listEntryName ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return lst;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number )
|
||||||
|
{
|
||||||
|
std::string moduleName;
|
||||||
|
std::string symName;
|
||||||
|
|
||||||
|
splitSymName( typeName, moduleName, symName );
|
||||||
|
|
||||||
|
ModulePtr module = Module::loadModuleByName( moduleName );
|
||||||
|
|
||||||
|
return module->getTypedVarArrayByTypeName( addr, symName, number );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
python::list getTypedVarArrayByType( ULONG64 offset, const TypeInfoPtr &typeInfo, ULONG number )
|
||||||
|
{
|
||||||
|
offset = addr64(offset);
|
||||||
|
|
||||||
|
python::list lst;
|
||||||
|
|
||||||
|
for( ULONG i = 0; i < number; ++i )
|
||||||
|
lst.append( TypedVar::getTypedVarByTypeInfo( typeInfo, offset + i * typeInfo->getSize() ) );
|
||||||
|
|
||||||
|
return lst;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
} // end pykd namespace
|
} // end pykd namespace
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include "typeinfo.h"
|
#include "typeinfo.h"
|
||||||
#include "intbase.h"
|
#include "intbase.h"
|
||||||
#include "dbgobj.h"
|
|
||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
#include "vardata.h"
|
#include "vardata.h"
|
||||||
|
|
||||||
@ -15,11 +14,11 @@ typedef boost::shared_ptr<TypedVar> TypedVarPtr;
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class TypedVar : public intBase, protected DbgObject {
|
class TypedVar : public intBase {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static TypedVarPtr getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData );
|
static TypedVarPtr getTypedVar( const TypeInfoPtr& typeInfo, VarDataPtr varData );
|
||||||
|
|
||||||
static TypedVarPtr getTypedVarByName( const std::string &varName );
|
static TypedVarPtr getTypedVarByName( const std::string &varName );
|
||||||
|
|
||||||
@ -86,7 +85,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData );
|
TypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData );
|
||||||
|
|
||||||
TypeInfoPtr m_typeInfo;
|
TypeInfoPtr m_typeInfo;
|
||||||
|
|
||||||
@ -104,11 +103,8 @@ class BasicTypedVar : public TypedVar {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BasicTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
|
BasicTypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar(typeInfo, varData)
|
||||||
: TypedVar(client, typeInfo, varData)
|
{}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
virtual std::string print();
|
virtual std::string print();
|
||||||
|
|
||||||
@ -124,10 +120,8 @@ class PtrTypedVar : public TypedVar {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PtrTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
|
PtrTypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar(typeInfo, varData)
|
||||||
: TypedVar(client, typeInfo, varData)
|
{}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string print();
|
virtual std::string print();
|
||||||
|
|
||||||
@ -145,10 +139,8 @@ class ArrayTypedVar: public TypedVar {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ArrayTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
|
ArrayTypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar(typeInfo, varData)
|
||||||
: TypedVar(client, typeInfo, varData)
|
{}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ULONG getElementCount() {
|
virtual ULONG getElementCount() {
|
||||||
return m_typeInfo->getCount();
|
return m_typeInfo->getCount();
|
||||||
@ -167,10 +159,8 @@ class UdtTypedVar : public TypedVar {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
UdtTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
|
UdtTypedVar( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar(typeInfo, varData)
|
||||||
: TypedVar(client, typeInfo, varData)
|
{}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -195,10 +185,8 @@ class BitFieldVar: public TypedVar {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BitFieldVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
|
BitFieldVar( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar( typeInfo, varData)
|
||||||
: TypedVar(client, typeInfo, varData)
|
{}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string printValue();
|
virtual std::string printValue();
|
||||||
|
|
||||||
@ -210,10 +198,8 @@ public:
|
|||||||
class EnumTypedVar : public TypedVar {
|
class EnumTypedVar : public TypedVar {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
EnumTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
|
EnumTypedVar( const TypeInfoPtr& typeInfo, VarDataPtr varData ) : TypedVar( typeInfo, varData)
|
||||||
: TypedVar(client, typeInfo, varData)
|
{}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string print();
|
virtual std::string print();
|
||||||
|
|
||||||
@ -224,5 +210,18 @@ public:
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TypedVarPtr containingRecordByName( ULONG64 addr, const std::string &typeName, const std::string &fieldName );
|
||||||
|
|
||||||
|
TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, const std::string &fieldName );
|
||||||
|
|
||||||
|
python::list getTypedVarListByTypeName( ULONG64 listHeadAddres, const std::string &typeName, const std::string &listEntryName );
|
||||||
|
|
||||||
|
python::list getTypedVarListByType( ULONG64 listHeadAddres, const TypeInfoPtr &typeInfo, const std::string &listEntryName );
|
||||||
|
|
||||||
|
python::list getTypedVarArrayByTypeName( ULONG64 addr, const std::string &typeName, ULONG number );
|
||||||
|
|
||||||
|
python::list getTypedVarArrayByType( ULONG64 addr, const TypeInfoPtr &typeInfo, ULONG number );
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
} // namespace pykd
|
} // namespace pykd
|
||||||
|
@ -515,4 +515,8 @@ private:
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void splitSymName( const std::string &fullName, std::string &moduleName, std::string &symbolName );
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
}; // namespace pykd
|
}; // namespace pykd
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#include "vardata.h"
|
#include "vardata.h"
|
||||||
#include "dbgmem.h"
|
#include "dbgengine.h"
|
||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -14,9 +14,8 @@ namespace pykd {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
VarDataMemory::VarDataMemory(CComPtr< IDebugDataSpaces4 > dataSpaces, ULONG64 addr)
|
VarDataMemory::VarDataMemory(ULONG64 addr) :
|
||||||
: m_dataSpaces(dataSpaces)
|
m_addr(addr)
|
||||||
, m_addr(addr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,30 +39,27 @@ ULONG64 VarDataMemory::getAddr() const
|
|||||||
|
|
||||||
VarDataPtr VarDataMemory::fork(ULONG offset) const
|
VarDataPtr VarDataMemory::fork(ULONG offset) const
|
||||||
{
|
{
|
||||||
return VarDataPtr( new VarDataMemory(m_dataSpaces, m_addr + offset) );
|
return VarDataPtr( new VarDataMemory(m_addr + offset) );
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void VarDataMemory::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const
|
void VarDataMemory::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const
|
||||||
{
|
{
|
||||||
readMemory(m_dataSpaces, m_addr + offset, buffer, length);
|
readMemory( m_addr + offset, buffer, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ULONG64 VarDataMemory::readPtr() const
|
ULONG64 VarDataMemory::readPtr() const
|
||||||
{
|
{
|
||||||
ULONG64 ptrValue = 0;
|
return ptrPtr( m_addr );
|
||||||
readMemoryPtr(m_dataSpaces, m_addr, &ptrValue);
|
|
||||||
return ptrValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
VarDataConst::VarDataConst(CComPtr< IDebugControl4 > control, pyDia::SymbolPtr symData)
|
VarDataConst::VarDataConst( SymbolPtr &symData) :
|
||||||
: m_control(control)
|
m_fieldOffset(0)
|
||||||
, m_fieldOffset(0)
|
|
||||||
, m_dataBuff( new std::vector< UCHAR >((size_t)symData->getType()->getSize(), 0) )
|
, m_dataBuff( new std::vector< UCHAR >((size_t)symData->getType()->getSize(), 0) )
|
||||||
{
|
{
|
||||||
VARIANT vtValue = {0};
|
VARIANT vtValue = {0};
|
||||||
@ -147,7 +143,7 @@ void VarDataConst::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const
|
|||||||
ULONG64 VarDataConst::readPtr() const
|
ULONG64 VarDataConst::readPtr() const
|
||||||
{
|
{
|
||||||
ULONG64 val = 0;
|
ULONG64 val = 0;
|
||||||
const ULONG length = (S_OK == m_control->IsPointer64Bit()) ? 8 : 4;
|
const ULONG length = ptrSize();
|
||||||
if (length > m_dataBuff->size())
|
if (length > m_dataBuff->size())
|
||||||
throw DbgException("Internal error in " __FUNCTION__);
|
throw DbgException("Internal error in " __FUNCTION__);
|
||||||
RtlCopyMemory(&val, &m_dataBuff->at(0), length);
|
RtlCopyMemory(&val, &m_dataBuff->at(0), length);
|
||||||
@ -156,9 +152,8 @@ ULONG64 VarDataConst::readPtr() const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
VarDataConst::VarDataConst(const VarDataConst &from, ULONG fieldOffset)
|
VarDataConst::VarDataConst(const VarDataConst &from, ULONG fieldOffset) :
|
||||||
: m_control(from.m_control)
|
m_fieldOffset(from.m_fieldOffset + fieldOffset)
|
||||||
, m_fieldOffset(from.m_fieldOffset + fieldOffset)
|
|
||||||
, m_dataBuff(from.m_dataBuff)
|
, m_dataBuff(from.m_dataBuff)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -6,75 +6,73 @@
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <array>
|
//#include <array>
|
||||||
#include <boost\smart_ptr\shared_ptr.hpp>
|
#include "symengine.h"
|
||||||
|
|
||||||
#include "diawrapper.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
// pointer to variable data access interface
|
class VarData;
|
||||||
interface IVarData;
|
typedef boost::shared_ptr< VarData > VarDataPtr;
|
||||||
typedef boost::shared_ptr< IVarData > VarDataPtr;
|
|
||||||
|
|
||||||
// access to variable data interface
|
// access to variable data interface
|
||||||
interface IVarData
|
class VarData
|
||||||
{
|
{
|
||||||
virtual ~IVarData() {}
|
public:
|
||||||
|
virtual ~VarData() {}
|
||||||
|
|
||||||
virtual std::string asString() const = 0;
|
virtual std::string asString() const = 0;
|
||||||
virtual ULONG64 getAddr() const = 0;
|
virtual ULONG64 getAddr() const = 0;
|
||||||
virtual VarDataPtr fork(ULONG offset) const = 0;
|
virtual VarDataPtr fork(ULONG offset) const = 0;
|
||||||
|
|
||||||
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const = 0;
|
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const = 0;
|
||||||
virtual ULONG64 readPtr() const = 0;
|
virtual ULONG64 readPtr() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// variable in memory
|
// variable in memory
|
||||||
class VarDataMemory : public IVarData
|
class VarDataMemory : public VarData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// IVarData implementation
|
// IVarData implementation
|
||||||
virtual std::string asString() const override;
|
virtual std::string asString() const;
|
||||||
virtual ULONG64 getAddr() const override;
|
virtual ULONG64 getAddr() const;
|
||||||
virtual VarDataPtr fork(ULONG offset) const override;
|
virtual VarDataPtr fork(ULONG offset) const;
|
||||||
|
|
||||||
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const override;
|
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const;
|
||||||
virtual ULONG64 readPtr() const override;
|
virtual ULONG64 readPtr() const;
|
||||||
|
|
||||||
static VarDataPtr factory(CComPtr< IDebugDataSpaces4 > dataSpaces, ULONG64 addr) {
|
static VarDataPtr factory(ULONG64 addr) {
|
||||||
return VarDataPtr( new VarDataMemory(dataSpaces, addr) );
|
return VarDataPtr( new VarDataMemory(addr) );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
VarDataMemory(CComPtr< IDebugDataSpaces4 > dataSpaces, ULONG64 addr);
|
VarDataMemory(ULONG64 addr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CComPtr< IDebugDataSpaces4 > m_dataSpaces;
|
|
||||||
ULONG64 m_addr;
|
ULONG64 m_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// constant variable
|
// constant variable
|
||||||
class VarDataConst : public IVarData
|
class VarDataConst : public VarData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// IVarData implementation
|
// IVarData implementation
|
||||||
virtual std::string asString() const override;
|
virtual std::string asString() const;
|
||||||
virtual ULONG64 getAddr() const override;
|
virtual ULONG64 getAddr() const;
|
||||||
virtual VarDataPtr fork(ULONG offset) const override;
|
virtual VarDataPtr fork(ULONG offset) const;
|
||||||
|
|
||||||
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const override;
|
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const;
|
||||||
virtual ULONG64 readPtr() const override;
|
virtual ULONG64 readPtr() const;
|
||||||
|
|
||||||
static VarDataPtr factory(CComPtr< IDebugControl4 > control, pyDia::SymbolPtr symData) {
|
static VarDataPtr factory(SymbolPtr &symData) {
|
||||||
return VarDataPtr( new VarDataConst(control, symData) );
|
return VarDataPtr( new VarDataConst(symData) );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
VarDataConst(CComPtr< IDebugControl4 > control, pyDia::SymbolPtr symData);
|
VarDataConst(SymbolPtr &symData);
|
||||||
VarDataConst(const VarDataConst &from, ULONG fieldOffset);
|
VarDataConst(const VarDataConst &from, ULONG fieldOffset);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -84,7 +82,6 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CComPtr< IDebugControl4 > m_control;
|
|
||||||
|
|
||||||
ULONG m_fieldOffset;
|
ULONG m_fieldOffset;
|
||||||
boost::shared_ptr< std::vector<UCHAR> > m_dataBuff;
|
boost::shared_ptr< std::vector<UCHAR> > m_dataBuff;
|
||||||
|
@ -318,6 +318,34 @@ ULONG ptrSize()
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string getSymbolByOffset( ULONG64 offset )
|
||||||
|
{
|
||||||
|
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
|
||||||
|
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
char nameBuf[0x100];
|
||||||
|
|
||||||
|
hres =
|
||||||
|
g_dbgEng->symbols->GetNameByOffset(
|
||||||
|
offset,
|
||||||
|
nameBuf,
|
||||||
|
sizeof(nameBuf),
|
||||||
|
NULL,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
std::string fullName( nameBuf );
|
||||||
|
|
||||||
|
size_t symPos = fullName.find ( '!' ) + 1;
|
||||||
|
|
||||||
|
std::string symbolName;
|
||||||
|
symbolName.assign( fullName, symPos, fullName.length() - symPos );
|
||||||
|
|
||||||
|
return symbolName;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import intbase
|
|||||||
import memtest
|
import memtest
|
||||||
import moduletest
|
import moduletest
|
||||||
import typeinfo
|
import typeinfo
|
||||||
|
import typedvar
|
||||||
|
|
||||||
def getTestSuite( singleName = "" ):
|
def getTestSuite( singleName = "" ):
|
||||||
if singleName == "":
|
if singleName == "":
|
||||||
@ -28,6 +28,7 @@ def getTestSuite( singleName = "" ):
|
|||||||
unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
|
unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
|
||||||
unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ),
|
unittest.TestLoader().loadTestsFromTestCase( memtest.MemoryTest ),
|
||||||
unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
|
unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
|
||||||
|
unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ),
|
||||||
] )
|
] )
|
||||||
else:
|
else:
|
||||||
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
|
return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
|
||||||
@ -46,6 +47,8 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
pykd.go()
|
pykd.go()
|
||||||
|
|
||||||
|
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run(getTestSuite( "typedvar.TypedVarTest.testPrint" ) )
|
||||||
|
|
||||||
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() )
|
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() )
|
||||||
|
|
||||||
pykd.killProcess( processId )
|
pykd.killProcess( processId )
|
||||||
|
@ -120,7 +120,7 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
self.assertEqual( 3, len( tvl ) )
|
self.assertEqual( 3, len( tvl ) )
|
||||||
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
|
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
|
||||||
|
|
||||||
tvl = target.module.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry" )
|
tvl = pykd.typedVarList( target.module.g_listHead, target.module.type("listStruct"), "listEntry" )
|
||||||
self.assertEqual( 3, len( tvl ) )
|
self.assertEqual( 3, len( tvl ) )
|
||||||
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
|
self.assertEqual( [1,2,3], [ tv.num for tv in tvl ] )
|
||||||
|
|
||||||
@ -128,11 +128,11 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
self.assertEqual( 3, len( tvl ) )
|
self.assertEqual( 3, len( tvl ) )
|
||||||
self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] )
|
self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] )
|
||||||
|
|
||||||
tvl = target.module.typedVarList( target.module.g_listHead1, target.module.type("listStruct1"), "next" )
|
tvl = pykd.typedVarList( target.module.g_listHead1, target.module.type("listStruct1"), "next" )
|
||||||
self.assertEqual( 3, len( tvl ) )
|
self.assertEqual( 3, len( tvl ) )
|
||||||
self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] )
|
self.assertEqual( [100,200,300], [ tv.num for tv in tvl ] )
|
||||||
|
|
||||||
tvl = target.module.typedVarList( target.module.g_childListHead, target.module.type("ChildEntryTest"), "m_next" )
|
tvl = pykd.typedVarList( target.module.g_childListHead, target.module.type("ChildEntryTest"), "m_next" )
|
||||||
self.assertEqual( 3, len( tvl ) )
|
self.assertEqual( 3, len( tvl ) )
|
||||||
self.assertEqual( [1000,2000,3000], [ tv.m_someBaseFiled2 for tv in tvl ] )
|
self.assertEqual( [1000,2000,3000], [ tv.m_someBaseFiled2 for tv in tvl ] )
|
||||||
self.assertEqual( [1001,2001,3001], [ tv.m_childFiled1 for tv in tvl ] )
|
self.assertEqual( [1001,2001,3001], [ tv.m_childFiled1 for tv in tvl ] )
|
||||||
@ -147,7 +147,7 @@ class TypedVarTest( unittest.TestCase ):
|
|||||||
self.assertEqual( 500, tvl[0].m_field1 )
|
self.assertEqual( 500, tvl[0].m_field1 )
|
||||||
self.assertEqual( False, tvl[1].m_field2 )
|
self.assertEqual( False, tvl[1].m_field2 )
|
||||||
|
|
||||||
tvl = target.module.typedVarArray( target.module.g_testArray, target.module.type("structTest"), 2 )
|
tvl = pykd.typedVarArray( target.module.g_testArray, target.module.type("structTest"), 2 )
|
||||||
self.assertEqual( 2, len( tvl ) )
|
self.assertEqual( 2, len( tvl ) )
|
||||||
self.assertEqual( 1, tvl[0].m_field3 )
|
self.assertEqual( 1, tvl[0].m_field3 )
|
||||||
self.assertEqual( 0, tvl[1].m_field4 )
|
self.assertEqual( 0, tvl[1].m_field4 )
|
||||||
|
Loading…
Reference in New Issue
Block a user