[0.1.x] added : typedVar class

git-svn-id: https://pykd.svn.codeplex.com/svn@70618 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2011-10-19 08:13:02 +00:00 committed by Mikhail I. Izmestev
parent 8c14fd3208
commit 379e97abf3
12 changed files with 217 additions and 25 deletions

View File

@ -13,6 +13,8 @@
#include "dbgpath.h"
#include "dbgcmd.h"
#include "dbgevent.h"
#include "typeinfo.h"
#include "typedvar.h"
using namespace pykd;
@ -125,6 +127,19 @@ BOOST_PYTHON_MODULE( pykd )
.def( "field", &pykd::TypeInfo::getField )
.def( "__getattr__", &pykd::TypeInfo::getField );
python::class_<pykd::TypedVar>("typedVar",
"Class of non-primitive type object, child class of typeClass. Data from target is copied into object instance",
python::no_init )
.def("getAddress", &pykd::TypedVar::getAddress,
"Return virtual address" )
.def("sizeof", &pykd::TypedVar::getSize,
"Return size of a variable in the target memory" );
//.def("data", &pykd::TypedVar::data,
// "Return raw string object with data stream" );
//.def("__getattr__", &pykd::TypedVar::getFieldWrap,
// "Return field of structure as an object attribute" );
python::class_<pykd::Module>("module", "Class representing executable module", python::no_init )
.def("begin", &pykd::Module::getBase,
"Return start address of the module" )
@ -146,6 +161,10 @@ BOOST_PYTHON_MODULE( pykd )
"Return rva of the symbol" )
.def("type", &pykd::Module::getTypeByName,
"Return typeInfo class by type name" )
.def("typedVar", &pykd::Module::getTypedVarByAddr,
"Return a typedVar class instance" )
.def("typedVar",&pykd::Module::getTypedVarByName,
"Return a typedVar class instance" )
.def("__getattr__", &pykd::Module::getSymbol,
"Return address of the symbol" );

View File

@ -153,14 +153,27 @@ Module::reloadSymbols()
///////////////////////////////////////////////////////////////////////////////////
TypeInfo
Module::getTypeByName( const std::string typeName )
Module::getTypeByName( const std::string &typeName )
{
pyDia::SymbolPtr typeSym = m_dia->getChildByName( typeName );
return TypeInfo( m_dia, typeName );
}
if ( typeSym->getSymTag() == SymTagData )
return TypeInfo( typeSym->getType() );
else
return TypeInfo( typeSym );
///////////////////////////////////////////////////////////////////////////////////
TypedVar
Module::getTypedVarByAddr( const std::string &typeName, ULONG64 addr )
{
return TypedVar( TypeInfo( m_dia, typeName ), addr );
}
///////////////////////////////////////////////////////////////////////////////////
TypedVar
Module::getTypedVarByName( const std::string &symName )
{
pyDia::SymbolPtr typeSym = m_dia->getChildByName( symName );
return TypedVar( TypeInfo( typeSym->getType() ), typeSym->getRva() + m_base );
}
///////////////////////////////////////////////////////////////////////////////////

View File

@ -5,6 +5,7 @@
#include "dbgobj.h"
#include "diawrapper.h"
#include "typeinfo.h"
#include "typedvar.h"
namespace pykd {
@ -66,7 +67,11 @@ public:
return sym->getRva();
}
TypeInfo getTypeByName( const std::string typeName );
TypeInfo getTypeByName( const std::string &typeName );
TypedVar getTypedVarByAddr( const std::string &typeName, ULONG64 addr );
TypedVar getTypedVarByName( const std::string &symName );
private:

View File

@ -437,6 +437,10 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\typeinfo.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
@ -499,6 +503,10 @@
RelativePath=".\stdafx.h"
>
</File>
<File
RelativePath=".\typedvar.h"
>
</File>
<File
RelativePath=".\typeinfo.h"
>

35
pykd/typedvar.h Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#include "typeinfo.h"
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
class TypedVar {
public:
TypedVar ( const TypeInfo& typeInfo, ULONG64 offset ) :
m_typeInfo( typeInfo ),
m_offset( offset )
{}
ULONG64 getAddress() const {
return m_offset;
}
ULONG getSize() {
return m_typeInfo.getSize();
}
private:
TypeInfo m_typeInfo;
ULONG64 m_offset;
};
///////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd

61
pykd/typeinfo.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "stdafx.h"
#include "typeinfo.h"
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
TypeInfo::TypeInfo( pyDia::GlobalScopePtr &diaScope, const std::string &symName ) :
m_offset( 0 )
{
pyDia::SymbolPtr typeSym = diaScope->getChildByName( symName );
if ( typeSym->getSymTag() == SymTagData )
{
m_dia = typeSym->getType();
}
else
{
m_dia = typeSym;
}
}
///////////////////////////////////////////////////////////////////////////////////
std::string
TypeInfo::getName()
{
std::stringstream sstr;
pyDia::SymbolPtr diaptr = m_dia;
int symtag = diaptr->getSymTag();
while( symtag == SymTagArrayType || symtag == SymTagPointerType )
{
if ( symtag == SymTagArrayType )
{
sstr << '[' << diaptr->getCount() << ']';
}
else
{
sstr << '*';
}
diaptr = diaptr->getType();
symtag = diaptr->getSymTag();
}
std::string typeName = symtag == SymTagBaseType ?
diaptr->getBasicTypeName( diaptr->getBaseType() ) :
diaptr->getName();
typeName += sstr.str();
return typeName;
};
///////////////////////////////////////////////////////////////////////////////////
}; // end namespace pykd

View File

@ -1,6 +1,7 @@
#pragma once
#include "dbgobj.h"
#include <string>
#include "diawrapper.h"
namespace pykd {
@ -11,10 +12,12 @@ class TypeInfo {
public:
TypeInfo( pyDia::SymbolPtr dia ) :
m_dia( dia ),
m_offset( 0 )
{}
TypeInfo( pyDia::GlobalScopePtr &diaScope, const std::string &symName );
TypeInfo( pyDia::SymbolPtr &diaType ) :
m_offset( 0 ),
m_dia( diaType )
{}
TypeInfo
getField( const std::string &fieldName ) {
@ -25,20 +28,16 @@ public:
}
std::string
getName() {
return m_dia->isBasicType() ?
m_dia->getBasicTypeName( m_dia->getBaseType() ) :
m_dia->getName();
}
getName();
ULONG
getOffset() {
return m_offset;
}
ULONG64
ULONG
getSize() {
return m_dia->getSize();
return (ULONG)m_dia->getSize();
}
private:

View File

@ -19,6 +19,7 @@ import diatest
import dbgcmd
import clienttest
import eventtest
import typedvar
def getTestSuite( singleName = "" ):
if singleName == "":
@ -27,6 +28,7 @@ def getTestSuite( singleName = "" ):
unittest.TestLoader().loadTestsFromTestCase( moduletest.ModuleTest ),
unittest.TestLoader().loadTestsFromTestCase( diatest.DiaTest ),
unittest.TestLoader().loadTestsFromTestCase( typeinfo.TypeInfoTest ),
unittest.TestLoader().loadTestsFromTestCase( typedvar.TypedVarTest ),
unittest.TestLoader().loadTestsFromTestCase( dbgcmd.DbgcmdTest ),
unittest.TestLoader().loadTestsFromTestCase( clienttest.DbgClientTest ),
unittest.TestLoader().loadTestsFromTestCase( eventtest.EventTest )
@ -48,5 +50,6 @@ if __name__ == "__main__":
target.module.reload();
suite = getTestSuite()
#suite = getTestSuite( "typedvar.TypedVarTest.testCtor" )
unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )

29
test/scripts/typedvar.py Normal file
View File

@ -0,0 +1,29 @@
#
#
#
import unittest
import target
import pykd
class TypedVarTest( unittest.TestCase ):
def testCtor( self ):
try: pykd.typedVar()
except RuntimeError: pass
try: pykd.typedVar( "structTest", target.module.g_structTest )
except RuntimeError: pass
tv = target.module.typedVar( "structTest", target.module.g_structTest )
tv = target.module.typedVar( "g_structTest" )
def testGetAddress( self ):
tv = target.module.typedVar( "structTest", target.module.g_structTest )
self.assertEqual( tv.getAddress(), target.module.g_structTest )
def testGetSize( self ):
tv1 = target.module.typedVar( "structTest", target.module.g_structTest )
self.assertEqual( 16, tv1.sizeof() )
#tv2 = target.module.typedVar( "structTest[]", target.module.g_testArray )
#self.assertEqual( tv1.sizeof()*2, tv2.sizeof() )

View File

@ -30,6 +30,14 @@ class TypeInfoTest( unittest.TestCase ):
self.assertEqual( "classChild", ti1.name() )
self.assertEqual( "Int", ti1.m_childField.name() )
self.assertEqual( "structTest", ti1.m_childField3.name() )
self.assertEqual( "structTest", target.module.type("g_structTest").name() )
def testArrayName( self ):
self.assertEqual( "structTest[2]", target.module.type("g_testArray").name() )
def testPtrName( self ):
self.assertEqual( "structTest*", target.module.type("g_structTestPtr").name() )
self.assertEqual( "structTest**", target.module.type("g_structTestPtrPtr").name() )
def testOffset( self ):
ti1 = target.module.type( "structTest" )

View File

@ -46,7 +46,12 @@ struct structTest {
USHORT m_field3;
};
structTest g_structTest = { 0, 500, true, 1 };
structTest g_structTest = { 0, 500, true, 1 };
structTest g_testArray[2] = { { 0, 500, true, 1 }, { 2, 1500, false, 1 } };
structTest *g_structTestPtr = &g_structTest;
structTest **g_structTestPtrPtr = &g_structTestPtr;
class classChild : public classBase {
public:
@ -79,6 +84,9 @@ void FuncWithName0()
std::cout << g_ulonglongValue;
std::cout << g_structTest.m_field0;
std::cout << g_testArray[1].m_field3;
std::cout << g_structTestPtr->m_field3;
std::cout << (*g_structTestPtrPtr)->m_field3;
}
void FuncWithName1(int a)

View File

@ -436,6 +436,10 @@
RelativePath="..\scripts\target.py"
>
</File>
<File
RelativePath="..\scripts\typedvar.py"
>
</File>
<File
RelativePath="..\scripts\typeinfo.py"
>