[0.2.x] fixed: some bugs with types

git-svn-id: https://pykd.svn.codeplex.com/svn@81947 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-12-21 07:06:53 +00:00 committed by Mikhail I. Izmestev
parent 9b4260f5f3
commit 18392dca83
13 changed files with 951 additions and 389 deletions

View File

@ -1,22 +1,30 @@
#include "stdafx.h" #include "stdafx.h"
#include "customtypes.h" #include "customtypes.h"
#include "dbgexcept.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
namespace pykd { namespace pykd {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
CustomTypeBase::CustomTypeBase(const std::string &name, ULONG pointerSize) TypeInfoPtr TypeBuilder::createStruct( const std::string &name, ULONG align )
: UdtFieldColl(name)
{ {
m_ptrSize = pointerSize ? pointerSize : ptrSize(); return TypeInfoPtr( new CustomStruct( name, m_ptrSize, align ? align : m_ptrSize ) );
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CustomTypeBase::throwIfFiledExist(const std::string &fieldName) TypeInfoPtr TypeBuilder::createUnion( const std::string &name, ULONG align )
{
return TypeInfoPtr( new CustomUnion( name, m_ptrSize, align ? align : m_ptrSize ) );
}
////////////////////////////////////////////////////////////////////////////////
void CustomBase::throwIfFiledExist(const std::string &fieldName)
{ {
bool fieldExist = false; bool fieldExist = false;
try try
@ -24,29 +32,22 @@ void CustomTypeBase::throwIfFiledExist(const std::string &fieldName)
lookupField(fieldName); lookupField(fieldName);
fieldExist = true; fieldExist = true;
} }
catch (const TypeException &except) catch (const TypeException&)
{ {
DBG_UNREFERENCED_PARAMETER(except);
} }
if (fieldExist) if (fieldExist)
throw TypeException(getName(), "duplicate field name: " + fieldName); throw TypeException(getName(), "duplicate field name: " + fieldName);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CustomTypeBase::throwIfTypeRecursive(TypeInfoPtr type) void CustomBase::throwIfTypeRecursive(TypeInfoPtr type)
{ {
if (type->is(this)) if (type->is(this))
throw TypeException(getName(), "wrong type of field"); throw TypeException(getName(), "recursive type definition");
return throwIfTypeRecursiveImpl(type); if ( !type->isUserDefined() )
}
////////////////////////////////////////////////////////////////////////////////
void CustomTypeBase::throwIfTypeRecursiveImpl(TypeInfoPtr type)
{
if (type->isEnum())
return; return;
try try
@ -58,7 +59,7 @@ void CustomTypeBase::throwIfTypeRecursiveImpl(TypeInfoPtr type)
if (fileldType->is(this)) if (fileldType->is(this))
throw TypeException(getName(), "wrong type of field"); throw TypeException(getName(), "wrong type of field");
throwIfTypeRecursiveImpl(fileldType); throwIfTypeRecursive(fileldType);
} }
} }
catch (const TypeException &except) catch (const TypeException &except)
@ -69,78 +70,188 @@ void CustomTypeBase::throwIfTypeRecursiveImpl(TypeInfoPtr type)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr CustomStruct::create( void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr &fieldType )
const std::string &name,
ULONG alignReq /*= 0*/,
ULONG pointerSize /*= 0*/)
{ {
return TypeInfoPtr( new CustomStruct(name, alignReq, pointerSize) ); throwIfFiledExist(fieldName);
throwIfTypeRecursive(fieldType);
CustomUdtField *field = new CustomUdtField( fieldType, fieldName );
ULONG fieldSize = fieldType->getSize();
ULONG offset = m_size;
ULONG align = fieldSize < m_align ? fieldSize : m_align;
offset += offset % align > 0 ? align - offset % align : 0;
field->setOffset( offset );
m_size = offset + fieldSize;
m_fields.push_back( UdtFieldPtr( field ) );
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
ULONG CustomStruct::getSize() void CustomUnion::appendField(const std::string &fieldName, TypeInfoPtr &fieldType )
{ {
if (Base::empty()) throwIfFiledExist(fieldName);
return 0; throwIfTypeRecursive(fieldType);
UdtUtils::Field &field = Base::last(); CustomUdtField *field = new CustomUdtField( fieldType, fieldName );
return field.m_offset + field.m_type->getSize();
ULONG fieldSize = fieldType->getSize();
m_size = fieldSize > m_size ? fieldSize : m_size;
m_fields.push_back( UdtFieldPtr( field ) );
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
{
Base::throwIfFiledExist(fieldName);
Base::throwIfTypeRecursive(fieldType);
ULONG offset = getSize();
offset += offset % (m_align ? m_align : fieldType->getAlignReq());
Base::push_back(
UdtUtils::Field(offset, fieldName, fieldType)
);
}
////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr CustomUnion::create(const std::string &name, ULONG pointerSize /*= 0*/)
{
return TypeInfoPtr( new CustomUnion(name, pointerSize) );
}
////////////////////////////////////////////////////////////////////////////////
ULONG CustomUnion::getSize()
{
ULONG size = 0;
for (ULONG i = 0; i < getFieldCount(); ++i)
{
ULONG fieldSize = lookupField(i).m_type->getSize();
if (fieldSize > size)
size = fieldSize;
}
return size;
}
////////////////////////////////////////////////////////////////////////////////
void CustomUnion::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
{
Base::throwIfFiledExist(fieldName);
Base::throwIfTypeRecursive(fieldType);
Base::push_back(
UdtUtils::Field(0, fieldName, fieldType)
);
}
//////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
//
TypeInfoPtr PtrToVoid() //CustomTypeBase::CustomTypeBase(const std::string &name, ULONG pointerSize)
{ // : UdtFieldColl(name)
return TypeInfoPtr( new PointerTypeInfo(ptrSize()) ); //{
} // m_ptrSize = pointerSize ? pointerSize : ptrSize();
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//void CustomTypeBase::throwIfFiledExist(const std::string &fieldName)
//{
// bool fieldExist = false;
// try
// {
// lookupField(fieldName);
// fieldExist = true;
// }
// catch (const TypeException &except)
// {
// DBG_UNREFERENCED_PARAMETER(except);
// }
// if (fieldExist)
// throw TypeException(getName(), "duplicate field name: " + fieldName);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//void CustomTypeBase::throwIfTypeRecursive(TypeInfoPtr type)
//{
// if (type->is(this))
// throw TypeException(getName(), "wrong type of field");
//
// return throwIfTypeRecursiveImpl(type);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//void CustomTypeBase::throwIfTypeRecursiveImpl(TypeInfoPtr type)
//{
// if (type->isEnum())
// return;
//
// try
// {
// const ULONG fields = type->getFieldCount();
// for (ULONG i = 0; i < fields; ++i)
// {
// TypeInfoPtr fileldType = type->getFieldByIndex(i);
// if (fileldType->is(this))
// throw TypeException(getName(), "wrong type of field");
//
// throwIfTypeRecursiveImpl(fileldType);
// }
// }
// catch (const TypeException &except)
// {
// DBG_UNREFERENCED_PARAMETER(except);
// }
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//TypeInfoPtr CustomStruct::create(
// const std::string &name,
// ULONG alignReq /*= 0*/,
// ULONG pointerSize /*= 0*/)
//{
// return TypeInfoPtr( new CustomStruct(name, alignReq, pointerSize) );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG CustomStruct::getSize()
//{
// if (Base::empty())
// return 0;
//
// UdtUtils::Field &field = Base::last();
// return field.m_offset + field.m_type->getSize();
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
//{
// Base::throwIfFiledExist(fieldName);
// Base::throwIfTypeRecursive(fieldType);
//
// ULONG offset = getSize();
// offset += offset % (m_align ? m_align : fieldType->getAlignReq());
// Base::push_back(
// UdtUtils::Field(offset, fieldName, fieldType)
// );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//TypeInfoPtr CustomUnion::create(const std::string &name, ULONG pointerSize /*= 0*/)
//{
// return TypeInfoPtr( new CustomUnion(name, pointerSize) );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//ULONG CustomUnion::getSize()
//{
// ULONG size = 0;
// for (ULONG i = 0; i < getFieldCount(); ++i)
// {
// ULONG fieldSize = lookupField(i).m_type->getSize();
// if (fieldSize > size)
// size = fieldSize;
// }
// return size;
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//void CustomUnion::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
//{
// Base::throwIfFiledExist(fieldName);
// Base::throwIfTypeRecursive(fieldType);
//
// Base::push_back(
// UdtUtils::Field(0, fieldName, fieldType)
// );
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//TypeInfoPtr PtrToVoid()
//{
// return TypeInfoPtr( new PointerTypeInfo(ptrSize()) );
//}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -4,90 +4,217 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "typeinfo.h" #include "typeinfo.h"
#include "win\dbgeng.h" #include "dbgengine.h"
#include <string>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
namespace pykd { namespace pykd {
class TypeBuilder {
public:
TypeBuilder( ULONG pointerSize = 0 )
{
m_ptrSize = pointerSize ? pointerSize : ptrSize();
}
TypeInfoPtr getUInt1B() { return TypeInfo::getBaseTypeInfo( "UInt1B" ); }
TypeInfoPtr getUInt2B() { return TypeInfo::getBaseTypeInfo( "UInt2B" ); }
TypeInfoPtr getUInt4B() { return TypeInfo::getBaseTypeInfo( "UInt4B" ); }
TypeInfoPtr getUInt8B() { return TypeInfo::getBaseTypeInfo( "UInt8B" ); }
TypeInfoPtr getInt1B() { return TypeInfo::getBaseTypeInfo( "Int1B" ); }
TypeInfoPtr getInt2B() { return TypeInfo::getBaseTypeInfo( "Int2B" ); }
TypeInfoPtr getInt4B() { return TypeInfo::getBaseTypeInfo( "Int4B" ); }
TypeInfoPtr getInt8B() { return TypeInfo::getBaseTypeInfo( "Int8B" ); }
TypeInfoPtr getLong() { return TypeInfo::getBaseTypeInfo( "Long" ); }
TypeInfoPtr getULong() { return TypeInfo::getBaseTypeInfo( "Ulong" ); }
TypeInfoPtr getBool() { return TypeInfo::getBaseTypeInfo( "Bool" ); }
TypeInfoPtr getChar() { return TypeInfo::getBaseTypeInfo( "Char" ); }
TypeInfoPtr getWChar() { return TypeInfo::getBaseTypeInfo( "WChar" ); }
TypeInfoPtr getVoidPtr() {
return TypeInfoPtr( new PointerTypeInfo(m_ptrSize) );
}
TypeInfoPtr createStruct( const std::string &name, ULONG align = 0 );
TypeInfoPtr createUnion( const std::string &name, ULONG align = 0);
private:
ULONG m_ptrSize;
};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class CustomTypeBase : public UdtFieldColl class CustomBase : public UdtTypeInfoBase
{ {
typedef UdtFieldColl Base;
protected: protected:
CustomTypeBase(const std::string &name, ULONG pointerSize);
CustomBase( const std::string &name, ULONG pointerSize, ULONG align ) :
UdtTypeInfoBase( name ),
m_size( 0 ),
m_ptrSize( pointerSize ),
m_align( align )
{}
void throwIfFiledExist(const std::string &fieldName); void throwIfFiledExist(const std::string &fieldName);
void throwIfTypeRecursive(TypeInfoPtr type); void throwIfTypeRecursive(TypeInfoPtr type);
private: protected:
void throwIfTypeRecursiveImpl(TypeInfoPtr type);
};
//////////////////////////////////////////////////////////////////////////////// virtual ULONG getSize() {
return m_size;
class CustomStruct : public CustomTypeBase }
{
typedef CustomTypeBase Base;
public:
static TypeInfoPtr create(const std::string &name, ULONG align = 0, ULONG pointerSize = 0);
protected: protected:
CustomStruct(const std::string &name, ULONG align, ULONG pointerSize)
: Base(name, pointerSize), m_name(name), m_align(align)
{
}
virtual std::string getName() override { ULONG m_ptrSize;
return m_name;
}
virtual ULONG getSize() override; ULONG m_align;
virtual void appendField(const std::string &fieldName, TypeInfoPtr fieldType) override; std::string m_name;
virtual std::string getTypeString() const override { ULONG m_size;
return "custom struct";
}
private:
std::string m_name;
ULONG m_align;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class CustomUnion : public CustomTypeBase class CustomStruct : public CustomBase
{ {
typedef CustomTypeBase Base;
public: public:
static TypeInfoPtr create(const std::string &name, ULONG pointerSize = 0);
CustomStruct( const std::string &name, ULONG ptrSize, ULONG align ) :
protected: CustomBase( name, ptrSize, align )
CustomUnion(const std::string &name, ULONG pointerSize) {}
: Base(name, pointerSize)
{
}
virtual ULONG getSize() override;
virtual void appendField(const std::string &fieldName, TypeInfoPtr fieldType) override;
virtual std::string getTypeString() const override {
return "custom union";
}
private: private:
std::string m_name;
virtual void appendField(const std::string &fieldName, TypeInfoPtr &fieldType );
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
TypeInfoPtr PtrToVoid(); class CustomUnion : public CustomBase
{
public:
CustomUnion( const std::string &name, ULONG ptrSize, ULONG align ) :
CustomBase( name, ptrSize, align )
{}
private:
virtual void appendField(const std::string &fieldName, TypeInfoPtr &fieldType );
};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////
//
//class CustomTypeBase : public UdtFieldColl
//{
// typedef UdtFieldColl Base;
//protected:
// CustomTypeBase(const std::string &name, ULONG pointerSize);
//
// void throwIfFiledExist(const std::string &fieldName);
// void throwIfTypeRecursive(TypeInfoPtr type);
//
//private:
// void throwIfTypeRecursiveImpl(TypeInfoPtr type);
//};
//
//////////////////////////////////////////////////////////////////////////////////
//
//class CustomStruct : public CustomTypeBase
//{
// typedef CustomTypeBase Base;
//public:
// static TypeInfoPtr create(const std::string &name, ULONG align = 0, ULONG pointerSize = 0);
//
//protected:
// CustomStruct(const std::string &name, ULONG align, ULONG pointerSize)
// : Base(name, pointerSize), m_name(name), m_align(align)
// {
// }
//
// virtual std::string getName() override {
// return m_name;
// }
//
// virtual ULONG getSize() override;
//
// virtual void appendField(const std::string &fieldName, TypeInfoPtr fieldType) override;
//
// virtual std::string getTypeString() const override {
// return "custom struct";
// }
//
//private:
// std::string m_name;
// ULONG m_align;
//};
//
//////////////////////////////////////////////////////////////////////////////////
//
//class CustomUnion : public CustomTypeBase
//{
// typedef CustomTypeBase Base;
//public:
// static TypeInfoPtr create(const std::string &name, ULONG pointerSize = 0);
//
//protected:
// CustomUnion(const std::string &name, ULONG pointerSize)
// : Base(name, pointerSize)
// {
// }
//
// virtual ULONG getSize() override;
//
// virtual void appendField(const std::string &fieldName, TypeInfoPtr fieldType) override;
//
// virtual std::string getTypeString() const override {
// return "custom union";
// }
//
//private:
// std::string m_name;
//};
//
//////////////////////////////////////////////////////////////////////////////////
//
//TypeInfoPtr PtrToVoid();
//
//////////////////////////////////////////////////////////////////////////////////
} // namespace pykd } // namespace pykd
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -20,6 +20,7 @@
#include "disasm.h" #include "disasm.h"
#include "stkframe.h" #include "stkframe.h"
#include "bpoint.h" #include "bpoint.h"
#include "eventhandler.h"
#include "win/dbgio.h" #include "win/dbgio.h"
#include "win/windbg.h" #include "win/windbg.h"
@ -59,11 +60,11 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceFile_, getSourceFile, 0, 1 );
BOOST_PYTHON_FUNCTION_OVERLOADS( setSoftwareBp_, setSoftwareBp, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( setSoftwareBp_, setSoftwareBp, 1, 2 );
BOOST_PYTHON_FUNCTION_OVERLOADS( setHardwareBp_, setHardwareBp, 3, 4 ); BOOST_PYTHON_FUNCTION_OVERLOADS( setHardwareBp_, setHardwareBp, 3, 4 );
BOOST_PYTHON_FUNCTION_OVERLOADS( CustomStruct_create, CustomStruct::create, 1, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( CustomUnion_create, CustomUnion::create, 1, 2 );
BOOST_PYTHON_FUNCTION_OVERLOADS( findSymbol_, TypeInfo::findSymbol, 1, 2 ); BOOST_PYTHON_FUNCTION_OVERLOADS( findSymbol_, TypeInfo::findSymbol, 1, 2 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( TypeBuilder_createStruct, TypeBuilder::createStruct, 1, 2 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( TypeBuilder_createUnion, TypeBuilder::createUnion, 1, 2 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumSymbols, Module::enumSymbols, 0, 1 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumSymbols, Module::enumSymbols, 0, 1 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumTypes, Module::enumTypes, 0, 1 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_enumTypes, Module::enumTypes, 0, 1 );
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_findSymbol, Module::getSymbolNameByVa, 1, 2 ); BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( Module_findSymbol, Module::getSymbolNameByVa, 1, 2 );
@ -286,12 +287,12 @@ BOOST_PYTHON_MODULE( pykd )
python::def( "setSymbolPath", &setSymbolPath, "Set current symbol path"); python::def( "setSymbolPath", &setSymbolPath, "Set current symbol path");
python::def( "appendSymbolPath", &appendSymbolPath, "Append current symbol path"); python::def( "appendSymbolPath", &appendSymbolPath, "Append current symbol path");
// custom types //// custom types
python::def( "createStruct", &CustomStruct::create, CustomStruct_create( python::args( "name", "align", "ptrSize" ), //python::def( "createStruct", &CustomStruct::create, CustomStruct_create( python::args( "name", "align", "ptrSize" ),
"Create empty structure. Use append() method for building" ) ); // "Create empty structure. Use append() method for building" ) );
python::def( "createUnion", &CustomUnion::create, CustomUnion_create( python::args( "name", "ptrSize" ), //python::def( "createUnion", &CustomUnion::create, CustomUnion_create( python::args( "name", "ptrSize" ),
"Create empty union. Use append() method for building" ) ); // "Create empty union. Use append() method for building" ) );
python::def( "pVoid", &PtrToVoid, "Create \"Void*\" type" ); //python::def( "pVoid", &PtrToVoid, "Create \"Void*\" type" );
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&>() )
@ -393,8 +394,8 @@ BOOST_PYTHON_MODULE( pykd )
.def("__init__", python::make_constructor(TypeInfo::getTypeInfoByName ) ) .def("__init__", python::make_constructor(TypeInfo::getTypeInfoByName ) )
.def( "name", &TypeInfo::getName ) .def( "name", &TypeInfo::getName )
.def( "size", &TypeInfo::getSize ) .def( "size", &TypeInfo::getSize )
.def( "staticOffset", &TypeInfo::getStaticOffset ) .def( "staticOffset", &TypeInfo::getStaticOffsetByName )
.def( "fieldOffset", &TypeInfo::getFieldOffsetByNameRecirsive ) .def( "fieldOffset", &TypeInfo::getFieldOffsetByNameRecursive )
.def( "bitOffset", &TypeInfo::getBitOffset ) .def( "bitOffset", &TypeInfo::getBitOffset )
.def( "bitWidth", &TypeInfo::getBitWidth ) .def( "bitWidth", &TypeInfo::getBitWidth )
.def( "field", &TypeInfo::getField ) .def( "field", &TypeInfo::getField )
@ -416,7 +417,7 @@ BOOST_PYTHON_MODULE( pykd )
"Return virtual address" ) "Return virtual address" )
.def("sizeof", &TypedVar::getSize, .def("sizeof", &TypedVar::getSize,
"Return size of a variable in the target memory" ) "Return size of a variable in the target memory" )
.def("fieldOffset", &TypedVar::getFieldOffsetByNameRecirsive, .def("fieldOffset", &TypedVar::getFieldOffsetByNameRecursive,
"Return target field offset" ) "Return target field offset" )
.def("field", &TypedVar::getField, .def("field", &TypedVar::getField,
"Return field of structure as an object attribute" ) "Return field of structure as an object attribute" )
@ -433,6 +434,29 @@ BOOST_PYTHON_MODULE( pykd )
.def("__getitem__", &TypedVar::getElementByIndex ) .def("__getitem__", &TypedVar::getElementByIndex )
.def("__getitem__", &TypedVar::getElementByIndexPtr ); .def("__getitem__", &TypedVar::getElementByIndexPtr );
python::class_<TypeBuilder>("typeBuilder",
"Class for building dynamically defined types", boost::python::no_init )
.def( python::init<ULONG>() )
.def( python::init<>() )
.add_property( "UInt1B", &TypeBuilder::getUInt1B )
.add_property( "UInt2B", &TypeBuilder::getUInt2B )
.add_property( "UInt4B", &TypeBuilder::getUInt4B )
.add_property( "UInt8B", &TypeBuilder::getUInt8B )
.add_property( "Int1B", &TypeBuilder::getInt1B )
.add_property( "Int2B", &TypeBuilder::getInt2B )
.add_property( "Int4B", &TypeBuilder::getInt4B )
.add_property( "Int8B", &TypeBuilder::getInt8B )
.add_property( "Long", &TypeBuilder::getLong )
.add_property( "ULong", &TypeBuilder::getLong )
.add_property( "Bool", &TypeBuilder::getLong )
.add_property( "Char", &TypeBuilder::getLong )
.add_property( "WChar", &TypeBuilder::getLong )
.add_property( "VoidPtr", &TypeBuilder::getVoidPtr )
.def( "createStruct", &TypeBuilder::createStruct, TypeBuilder_createStruct( python::args( "name", "align" ),
"create custom struct" ) )
.def( "createUnion", &TypeBuilder::createUnion, TypeBuilder_createUnion( python::args( "name", "align" ),
"create custom union" ) );
python::class_<CpuReg, python::bases<intBase> >( python::class_<CpuReg, python::bases<intBase> >(
"cpuReg", "CPU regsiter class", boost::python::no_init ) "cpuReg", "CPU regsiter class", boost::python::no_init )
.def( "name", &CpuReg::name, "The name of the regsiter" ) .def( "name", &CpuReg::name, "The name of the regsiter" )

View File

@ -265,21 +265,23 @@ UdtTypedVar::getField( const std::string &fieldName )
{ {
TypeInfoPtr fieldType = m_typeInfo->getField( fieldName ); TypeInfoPtr fieldType = m_typeInfo->getField( fieldName );
if ( fieldType->isStaticMember() ) if ( m_typeInfo->isStaticMember(fieldName) )
{ {
if ( fieldType->getStaticOffset() == 0 ) ULONG64 staticOffset = m_typeInfo->getStaticOffsetByName( fieldName );
if ( staticOffset == 0 )
throw ImplementException( __FILE__, __LINE__, "Fix ME"); throw ImplementException( __FILE__, __LINE__, "Fix ME");
return TypedVar::getTypedVar( fieldType, VarDataMemory::factory(fieldType->getStaticOffset() ) ); return TypedVar::getTypedVar( fieldType, VarDataMemory::factory(staticOffset) );
} }
ULONG fieldOffset = 0; ULONG fieldOffset = 0;
fieldOffset = m_typeInfo->getFieldOffsetByNameRecirsive(fieldName); fieldOffset = m_typeInfo->getFieldOffsetByNameRecursive(fieldName);
if ( fieldType->isVirtualMember() ) if ( m_typeInfo->isVirtualMember( fieldName ) )
{ {
fieldOffset += getVirtualBaseDisplacement( fieldType ); fieldOffset += getVirtualBaseDisplacement( fieldName );
} }
return TypedVar::getTypedVar( fieldType, m_varData->fork(fieldOffset) ); return TypedVar::getTypedVar( fieldType, m_varData->fork(fieldOffset) );
@ -290,23 +292,27 @@ UdtTypedVar::getField( const std::string &fieldName )
python::object python::object
UdtTypedVar::getElementByIndex( ULONG index ) UdtTypedVar::getElementByIndex( ULONG index )
{ {
TypeInfoPtr fieldType = m_typeInfo->getFieldByIndex(index); TypeInfoPtr fieldType = m_typeInfo->getFieldByIndex( index );
if ( fieldType->isStaticMember() ) if ( m_typeInfo->isStaticMemberByIndex(index) )
{ {
if ( fieldType->getStaticOffset() == 0 ) ULONG64 staticOffset = m_typeInfo->getStaticOffsetByIndex( index );
if ( staticOffset == 0 )
throw ImplementException( __FILE__, __LINE__, "Fix ME"); throw ImplementException( __FILE__, __LINE__, "Fix ME");
return python::make_tuple( return python::make_tuple(
m_typeInfo->getFieldNameByIndex(index), m_typeInfo->getFieldNameByIndex(index),
TypedVar::getTypedVar(fieldType, VarDataMemory::factory(fieldType->getStaticOffset() ) ) ); TypedVar::getTypedVar( fieldType, VarDataMemory::factory(staticOffset) ) );
} }
ULONG fieldOffset = m_typeInfo->getFieldOffsetByIndex(index); ULONG fieldOffset = 0;
if ( fieldType->isVirtualMember() ) fieldOffset = m_typeInfo->getFieldOffsetByIndex(index);
if ( m_typeInfo->isVirtualMemberByIndex( index ) )
{ {
fieldOffset += getVirtualBaseDisplacement( fieldType ); fieldOffset += getVirtualBaseDisplacementByIndex( index );
} }
return python::make_tuple( return python::make_tuple(
@ -316,12 +322,30 @@ UdtTypedVar::getElementByIndex( ULONG index )
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
LONG UdtTypedVar::getVirtualBaseDisplacement( TypeInfoPtr& typeInfo ) LONG UdtTypedVar::getVirtualBaseDisplacement( const std::string &fieldName )
{ {
ULONG virtualBasePtr, virtualDispIndex, virtualDispSize; ULONG virtualBasePtr, virtualDispIndex, virtualDispSize;
typeInfo->getVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize ); m_typeInfo->getVirtualDisplacement( fieldName, virtualBasePtr, virtualDispIndex, virtualDispSize );
ULONG64 vbtableOffset = m_varData->fork( virtualBasePtr )->readPtr( typeInfo->ptrSize() ); ULONG64 vbtableOffset = m_varData->fork( virtualBasePtr )->readPtr( m_typeInfo->ptrSize() );
VarDataPtr vbtable = VarDataMemory::factory(vbtableOffset);
LONG displacement = 0;
vbtable->read( &displacement, sizeof(displacement), virtualDispIndex*virtualDispSize );
return virtualBasePtr + displacement;
}
///////////////////////////////////////////////////////////////////////////////
LONG UdtTypedVar::getVirtualBaseDisplacementByIndex( ULONG index )
{
ULONG virtualBasePtr, virtualDispIndex, virtualDispSize;
m_typeInfo->getVirtualDisplacementByIndex( index, virtualBasePtr, virtualDispIndex, virtualDispSize );
ULONG64 vbtableOffset = m_varData->fork( virtualBasePtr )->readPtr( m_typeInfo->ptrSize() );
VarDataPtr vbtable = VarDataMemory::factory(vbtableOffset); VarDataPtr vbtable = VarDataMemory::factory(vbtableOffset);
@ -345,21 +369,23 @@ std::string UdtTypedVar::print()
TypeInfoPtr fieldType = m_typeInfo->getFieldByIndex(i); TypeInfoPtr fieldType = m_typeInfo->getFieldByIndex(i);
TypedVarPtr fieldVar; TypedVarPtr fieldVar;
if ( fieldType->isStaticMember() ) if ( m_typeInfo->isStaticMemberByIndex(i) )
{ {
if ( fieldType->getStaticOffset() != 0 ) ULONG64 staticOffset = m_typeInfo->getStaticOffsetByIndex(i);
fieldVar = TypedVar::getTypedVar( fieldType, VarDataMemory::factory( fieldType->getStaticOffset() ) );
sstr << " =" << std::right << std::setw(10) << std::setfill('0') << std::hex << fieldType->getStaticOffset(); if ( staticOffset != 0 )
fieldVar = TypedVar::getTypedVar( fieldType, VarDataMemory::factory( staticOffset ) );
sstr << " =" << std::right << std::setw(10) << std::setfill('0') << std::hex << staticOffset;
sstr << " " << std::left << std::setw(18) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':'; sstr << " " << std::left << std::setw(18) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':';
} }
else else
{ {
ULONG fieldOffset = m_typeInfo->getFieldOffsetByIndex(i); ULONG fieldOffset = m_typeInfo->getFieldOffsetByIndex(i);
if ( fieldType->isVirtualMember() ) if ( m_typeInfo->isVirtualMemberByIndex( i ) )
{ {
fieldOffset += getVirtualBaseDisplacement( fieldType ); fieldOffset += getVirtualBaseDisplacementByIndex( i );
} }
fieldVar = TypedVar::getTypedVar( fieldType, m_varData->fork(fieldOffset) ); fieldVar = TypedVar::getTypedVar( fieldType, m_varData->fork(fieldOffset) );
@ -514,7 +540,7 @@ TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, c
{ {
addr = addr64(addr); addr = addr64(addr);
VarDataPtr varData = VarDataMemory::factory( addr - typeInfo->getFieldOffsetByNameRecirsive(fieldName) ); VarDataPtr varData = VarDataMemory::factory( addr - typeInfo->getFieldOffsetByNameRecursive(fieldName) );
return TypedVar::getTypedVar( typeInfo, varData ); return TypedVar::getTypedVar( typeInfo, varData );
} }
@ -549,7 +575,7 @@ python::list getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &
if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) ) if ( fieldTypeInfo->getName() == ( typeInfo->getName() + "*" ) )
{ {
for( entryAddress = ptrFunc( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrFunc( entryAddress + typeInfo->getFieldOffsetByNameRecirsive(listEntryName) ) ) for( entryAddress = ptrFunc( listHeadAddress ); addr64(entryAddress) != listHeadAddress && entryAddress != NULL; entryAddress = ptrFunc( entryAddress + typeInfo->getFieldOffsetByNameRecursive(listEntryName) ) )
lst.append( TypedVar::getTypedVarByTypeInfo( typeInfo, entryAddress ) ); lst.append( TypedVar::getTypedVarByTypeInfo( typeInfo, entryAddress ) );
} }
else else

View File

@ -34,8 +34,8 @@ public:
return m_size; return m_size;
} }
ULONG getFieldOffsetByNameRecirsive(const std::string &fieldName) { ULONG getFieldOffsetByNameRecursive(const std::string &fieldName) {
return m_typeInfo->getFieldOffsetByNameRecirsive(fieldName); return m_typeInfo->getFieldOffsetByNameRecursive(fieldName);
} }
TypeInfoPtr TypeInfoPtr
@ -87,6 +87,9 @@ protected:
TypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData ); TypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData );
virtual ~TypedVar()
{}
TypeInfoPtr m_typeInfo; TypeInfoPtr m_typeInfo;
VarDataPtr m_varData; VarDataPtr m_varData;
@ -171,12 +174,13 @@ protected:
virtual TypedVarPtr getField( const std::string &fieldName ); virtual TypedVarPtr getField( const std::string &fieldName );
virtual ULONG getElementCount() { virtual ULONG getElementCount() {
return m_typeInfo->getFieldCount(); return m_typeInfo->getFieldCount();
} }
virtual python::object getElementByIndex( ULONG index ); virtual python::object getElementByIndex( ULONG index );
LONG getVirtualBaseDisplacement( TypeInfoPtr& typeInfo ); LONG getVirtualBaseDisplacement( const std::string &fieldName );
LONG getVirtualBaseDisplacementByIndex( ULONG index );
}; };
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////

View File

@ -609,51 +609,39 @@ TypeInfoPtr TypeInfo::ptrTo()
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
ULONG64 TypeInfo::getStaticOffset() std::string UdtTypeInfoBase::print()
{
if ( !m_staticMember )
throw TypeException( getName(), "This is not a static member" );
return m_staticOffset;
}
/////////////////////////////////////////////////////////////////////////////////////
std::string UdtFieldColl::print()
{ {
std::stringstream sstr; std::stringstream sstr;
sstr << getTypeString() << ": " << getName() << " Size: 0x" << std::hex << getSize() << " (" << std::dec << getSize() << ")" << std::endl; sstr << "class/struct " << ": " << getName() << " Size: 0x" << std::hex << getSize() << " (" << std::dec << getSize() << ")" << std::endl;
ULONG fieldCount = getFieldCount(); ULONG fieldCount = getFieldCount();
for ( ULONG i = 0; i < fieldCount; ++i ) for ( ULONG i = 0; i < fieldCount; ++i )
{ {
const UdtUtils::Field &udtField = lookupField(i); UdtFieldPtr& udtField = lookupField(i);
TypeInfoPtr fieldType = udtField.m_type;
if ( fieldType->isStaticMember() ) if ( udtField->isStaticMember() )
{
sstr << " =" << std::right << std::setw(10) << std::setfill('0') << std::hex << fieldType->getStaticOffset();
sstr << " " << std::left << std::setw(18) << std::setfill(' ') << udtField.m_name << ':';
}
else
if ( fieldType->isVirtualMember() )
{ {
ULONG virtualBasePtr, virtualDispIndex, virtualDispSize; sstr << " =" << std::right << std::setw(10) << std::setfill('0') << std::hex << udtField->getStaticOffset();
fieldType->getVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize ); sstr << " " << std::left << std::setw(18) << std::setfill(' ') << udtField->getName() << ':';
sstr << " virtual base " << fieldType->getVirtualBase()->getName();
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << udtField.m_offset;
sstr << " " << udtField.m_name << ':';
} }
else else
{ {
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << udtField.m_offset; if ( udtField->isVirtualMember() )
sstr << " " << std::left << std::setw(24) << std::setfill(' ') << udtField.m_name << ':'; {
sstr << " virtual base " << udtField->getVirtualBaseClassName();
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << udtField->getOffset();
sstr << " " << udtField->getName() << ':';
}
else
{
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << udtField->getOffset();
sstr << " " << std::left << std::setw(24) << std::setfill(' ') << udtField->getName() << ':';
}
} }
sstr << " " << std::left << fieldType->getName(); sstr << " " << std::left << udtField->getTypeInfo()->getName();
sstr << std::endl; sstr << std::endl;
} }
@ -662,14 +650,40 @@ std::string UdtFieldColl::print()
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
ULONG UdtFieldColl::getAlignReq() ULONG UdtTypeInfoBase::getAlignReq()
{ {
ULONG alignReq = 1; //ULONG alignReq = 1;
const ULONG fieldCount = getFieldCount(); //const ULONG fieldCount = getFieldCount();
for ( ULONG i = 0; i < fieldCount; ++i ) //for ( ULONG i = 0; i < fieldCount; ++i )
alignReq = max(alignReq, lookupField(i).m_type->getAlignReq()); // alignReq = max(alignReq, lookupField(i).m_type->getAlignReq());
return alignReq; //return alignReq;
throw ImplementException( __FILE__, __LINE__, "TODO" );
}
/////////////////////////////////////////////////////////////////////////////////////
void UdtTypeInfoBase::getVirtualDisplacement( const std::string& fieldName, ULONG &virtualBasePtr, ULONG &virtualDispIndex, ULONG &virtualDispSize )
{
const UdtFieldPtr &field = lookupField(fieldName);
if ( !field->isVirtualMember() )
throw TypeException( getName(), "field is not a virtual member" );
field->getVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
}
/////////////////////////////////////////////////////////////////////////////////////
void UdtTypeInfoBase::getVirtualDisplacementByIndex( ULONG index, ULONG &virtualBasePtr, ULONG &virtualDispIndex, ULONG &virtualDispSize )
{
const UdtFieldPtr &field = lookupField(index);
if ( !field->isVirtualMember() )
throw TypeException( getName(), "field is not a virtual member" );
field->getVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
@ -700,52 +714,34 @@ void UdtTypeInfo::getFields(
else else
if ( symTag == SymTagData ) if ( symTag == SymTagData )
{ {
TypeInfoPtr ti = TypeInfo::getTypeInfo( childSym ); SymbolUdtField *fieldPtr = new SymbolUdtField( childSym, childSym->getName() );
ULONG fieldOffset = 0;
switch ( childSym->getDataKind() ) switch ( childSym->getDataKind() )
{ {
case DataIsMember: case DataIsMember:
fieldPtr->setOffset( startOffset + childSym->getOffset() );
if ( baseVirtualSym )
{
ti->setVirtualBase(
TypeInfo::getTypeInfo(baseVirtualSym),
virtualBasePtr,
virtualDispIndex,
virtualDispSize );
}
fieldOffset = startOffset + childSym->getOffset();
break; break;
case DataIsStaticMember: case DataIsStaticMember:
ti->setStaticOffset( childSym->getVa() ); fieldPtr->setStaticOffset( childSym->getVa() );
break; break;
} }
UdtFieldColl::push_back( if ( baseVirtualSym )
UdtUtils::Field( fieldOffset, childSym->getName(), ti ) fieldPtr->setVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
);
m_fields.push_back( UdtFieldPtr( fieldPtr ) );
} }
else else
if ( symTag == SymTagVTable ) if ( symTag == SymTagVTable )
{ {
TypeInfoPtr ti = TypeInfo::getTypeInfo( childSym ); SymbolUdtField *fieldPtr = new SymbolUdtField( childSym, "__VFN_table" );
fieldPtr->setOffset( startOffset + childSym->getOffset() );
if ( baseVirtualSym ) if ( baseVirtualSym )
{ fieldPtr->setVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
ti->setVirtualBase(
TypeInfo::getTypeInfo(baseVirtualSym),
virtualBasePtr,
virtualDispIndex,
virtualDispSize );
}
UdtFieldColl::push_back( m_fields.push_back( UdtFieldPtr( fieldPtr ) );
UdtUtils::Field( startOffset + childSym->getOffset(), "__VFN_table", ti )
);
} }
} }
} }
@ -777,11 +773,8 @@ void UdtTypeInfo::getVirtualFields()
void UdtTypeInfo::refreshFields() void UdtTypeInfo::refreshFields()
{ {
if ( UdtFieldColl::empty() ) getFields( m_dia, SymbolPtr() );
{ getVirtualFields();
getFields( m_dia, SymbolPtr() );
getVirtualFields();
}
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////

View File

@ -52,16 +52,13 @@ public:
public: public:
TypeInfo() : TypeInfo() :
m_staticOffset( 0 ),
m_constant( false ), m_constant( false ),
m_staticMember( false ),
m_virtualMember( false ),
m_virtualBasePtr( 0 ),
m_virtualDispIndex( 0 ),
m_virtualDispSize( 0 ),
m_ptrSize( 0 ) m_ptrSize( 0 )
{} {}
virtual ~TypeInfo()
{}
virtual std::string print() { virtual std::string print() {
std::stringstream sstr; std::stringstream sstr;
sstr << "Type name: " << getName(); sstr << "Type name: " << getName();
@ -85,7 +82,7 @@ public:
throw TypeException( getName(), "type is not a struct" ); throw TypeException( getName(), "type is not a struct" );
} }
virtual ULONG getFieldOffsetByNameRecirsive( const std::string &fieldName ) { virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName ) {
throw TypeException( getName(), "type is not a struct" ); throw TypeException( getName(), "type is not a struct" );
} }
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) { virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
@ -100,6 +97,46 @@ public:
throw TypeException( getName(), "type is not a struct" ); throw TypeException( getName(), "type is not a struct" );
} }
virtual bool isStaticMember( const std::string& fieldName )
{
throw TypeException( getName(), "type is not a struct" );
}
virtual bool isStaticMemberByIndex( ULONG index )
{
throw TypeException( getName(), "type is not a struct" );
}
virtual ULONG64 getStaticOffsetByName( const std::string& fieldName )
{
throw TypeException( getName(), "type is not a struct" );
}
virtual ULONG64 getStaticOffsetByIndex( ULONG index )
{
throw TypeException( getName(), "type is not a struct" );
}
virtual bool isVirtualMember( const std::string& fieldName )
{
throw TypeException( getName(), "type is not a struct" );
}
virtual bool isVirtualMemberByIndex( ULONG index )
{
throw TypeException( getName(), "type is not a struct" );
}
virtual void getVirtualDisplacement( const std::string& fieldName, ULONG &virtualBasePtr, ULONG &virtualDispIndex, ULONG &virtualDispSize )
{
throw TypeException( getName(), "type is not a struct" );
}
virtual void getVirtualDisplacementByIndex( ULONG index, ULONG &virtualBasePtr, ULONG &virtualDispIndex, ULONG &virtualDispSize )
{
throw TypeException( getName(), "type is not a struct" );
}
virtual BaseTypeVariant getValue(); virtual BaseTypeVariant getValue();
virtual bool isBasicType() { virtual bool isBasicType() {
@ -158,8 +195,8 @@ public:
throw PyException( PyExc_TypeError, "object is unsubscriptable"); throw PyException( PyExc_TypeError, "object is unsubscriptable");
} }
virtual void appendField(const std::string &fieldName, TypeInfoPtr fieldType) { virtual void appendField(const std::string &fieldName, TypeInfoPtr &fieldType) {
throw TypeException( getName(), "type is not is not extensible" ); throw TypeException( getName(), "type is not is not editable" );
} }
TypeInfoPtr ptrTo(); TypeInfoPtr ptrTo();
@ -178,42 +215,6 @@ public:
return m_constant == true; return m_constant == true;
} }
bool isStaticMember() const
{
return m_staticMember == true;
}
bool isVirtualMember() const
{
return m_virtualMember == true;
}
void setStaticOffset( ULONG64 offset ) {
m_staticOffset = offset;
m_staticMember = true;
}
void setVirtualBase( TypeInfoPtr virtualBase, LONG virtualBasePtr, ULONG virtualDispIndex, ULONG virtualDispSize )
{
m_virtualMember = true;
m_virtualBaseType = virtualBase;
m_virtualBasePtr = virtualBasePtr;
m_virtualDispIndex = virtualDispIndex;
m_virtualDispSize = virtualDispSize;
}
ULONG64 getStaticOffset();
void getVirtualDisplacement( ULONG &virtualBasePtr, ULONG &virtualDispIndex, ULONG &virtualDispSize ) {
virtualBasePtr = m_virtualBasePtr;
virtualDispIndex = m_virtualDispIndex;
virtualDispSize = m_virtualDispSize;
};
TypeInfoPtr getVirtualBase() {
return m_virtualBaseType;
}
bool is(TypeInfo *rhs) const { bool is(TypeInfo *rhs) const {
return this == rhs; return this == rhs;
} }
@ -232,24 +233,10 @@ protected:
static static
TypeInfoPtr getRecurciveComplexType( TypeInfoPtr &lowestType, std::string &suffix, ULONG ptrSize ); TypeInfoPtr getRecurciveComplexType( TypeInfoPtr &lowestType, std::string &suffix, ULONG ptrSize );
ULONG64 m_staticOffset;
bool m_constant; bool m_constant;
bool m_staticMember;
bool m_virtualMember;
BaseTypeVariant m_constantValue; BaseTypeVariant m_constantValue;
LONG m_virtualBasePtr;
ULONG m_virtualDispIndex;
ULONG m_virtualDispSize;
TypeInfoPtr m_virtualBaseType;
ULONG m_ptrSize; ULONG m_ptrSize;
}; };
@ -323,40 +310,60 @@ private:
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
class UdtFieldColl : public TypeInfo class UdtTypeInfoBase : public TypeInfo
{ {
protected: protected:
virtual std::string getName() { virtual std::string getName() {
return m_fields.getName(); return m_name;
} }
virtual TypeInfoPtr getField( const std::string &fieldName ) { virtual TypeInfoPtr getField( const std::string &fieldName ) {
return lookupField(fieldName).m_type; return lookupField(fieldName)->getTypeInfo();
} }
virtual TypeInfoPtr getFieldByIndex( ULONG index ) { virtual TypeInfoPtr getFieldByIndex( ULONG index ) {
return lookupField(index).m_type; return lookupField(index)->getTypeInfo();
} }
virtual std::string getFieldNameByIndex( ULONG index ) { virtual std::string getFieldNameByIndex( ULONG index ) {
return lookupField(index).m_name; return lookupField(index)->getName();
} }
virtual ULONG getFieldOffsetByNameRecirsive( const std::string &fieldName ) { virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName ) {
return UdtUtils::getFieldOffsetRecirsive( shared_from_this(), fieldName ); return getFieldOffsetRecursive( shared_from_this(), fieldName );
} }
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) { virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
return lookupField(fieldName).m_offset; return lookupField(fieldName)->getOffset();
} }
virtual ULONG getFieldOffsetByIndex( ULONG index ) { virtual ULONG getFieldOffsetByIndex( ULONG index ) {
return lookupField(index).m_offset; return lookupField(index)->getOffset();
}
virtual bool isStaticMember( const std::string& fieldName ) {
return lookupField(fieldName)->isStaticMember();
}
virtual bool isStaticMemberByIndex( ULONG index ) {
return lookupField(index)->isStaticMember();
}
virtual ULONG64 getStaticOffsetByName( const std::string& fieldName ) {
return lookupField(fieldName)->getStaticOffset();
}
virtual ULONG64 getStaticOffsetByIndex( ULONG index ) {
return lookupField(index)->getStaticOffset();
} }
virtual ULONG getFieldCount() { virtual ULONG getFieldCount() {
refreshFields(); if ( !m_fieldsGot )
return (ULONG)m_fields.size(); {
refreshFields();
m_fieldsGot = true;
}
return m_fields.count();
} }
virtual ULONG getElementCount() { virtual ULONG getElementCount() {
@ -375,42 +382,70 @@ protected:
virtual ULONG getAlignReq() override; virtual ULONG getAlignReq() override;
protected: virtual bool isVirtualMember( const std::string& fieldName )
UdtFieldColl(const std::string &typeName) : m_fields(typeName) {} {
return lookupField(fieldName)->isVirtualMember();
virtual void refreshFields() {}
virtual std::string getTypeString() const = 0;
bool empty() const {
return m_fields.empty();
} }
void push_back(const UdtUtils::Field &field) { virtual bool isVirtualMemberByIndex( ULONG index )
{
return lookupField(index)->isVirtualMember();
}
virtual void getVirtualDisplacement( const std::string& fieldName, ULONG &virtualBasePtr, ULONG &virtualDispIndex, ULONG &virtualDispSize );
virtual void getVirtualDisplacementByIndex( ULONG index, ULONG &virtualBasePtr, ULONG &virtualDispIndex, ULONG &virtualDispSize );
protected:
UdtTypeInfoBase(const std::string &typeName) :
m_name(typeName),
m_fieldsGot( false )
{}
virtual void refreshFields() {}
void push_back(const UdtFieldPtr &field) {
m_fields.push_back(field); m_fields.push_back(field);
} }
template <typename T> template <typename T>
const UdtUtils::Field &lookupField( T index) { const UdtFieldPtr &lookupField( T index)const {
refreshFields(); if ( !m_fieldsGot )
{
refreshFields();
m_fieldsGot = true;
}
return m_fields.lookup(index); return m_fields.lookup(index);
} }
UdtUtils::Field &last(){ template <typename T>
return *m_fields.rbegin(); UdtFieldPtr &lookupField( T index) {
if ( !m_fieldsGot )
{
refreshFields();
m_fieldsGot = true;
}
return m_fields.lookup(index);
} }
private: protected:
UdtUtils::FieldCollection m_fields;
bool m_fieldsGot;
FieldCollection m_fields;
std::string m_name;
}; };
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
class UdtTypeInfo : public UdtFieldColl class UdtTypeInfo : public UdtTypeInfoBase
{ {
public: public:
UdtTypeInfo (SymbolPtr &symbol ) : UdtTypeInfo (SymbolPtr &symbol ) :
UdtFieldColl( symbol->getName() ), UdtTypeInfoBase( symbol->getName() ),
m_dia( symbol ) m_dia( symbol )
{ {
} }
@ -423,10 +458,6 @@ protected:
virtual void refreshFields() override; virtual void refreshFields() override;
virtual std::string getTypeString() const override {
return "struct/class";
}
void getFields( void getFields(
SymbolPtr &rootSym, SymbolPtr &rootSym,
SymbolPtr &baseVirtualSym, SymbolPtr &baseVirtualSym,

View File

@ -10,33 +10,58 @@
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
namespace pykd { namespace pykd {
namespace UdtUtils {
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
const Field &FieldCollection::lookup(ULONG index) const const UdtFieldPtr& FieldCollection::lookup(ULONG index) const
{ {
if (index >= Base::size()) if (index >= m_fields.size() )
throw PyException( PyExc_IndexError, m_baseTypeName + " index out of range" ); throw PyException( PyExc_IndexError, "index out of range" );
return at(index);
return m_fields[index];
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
const Field &FieldCollection::lookup(const std::string &name) const const UdtFieldPtr& FieldCollection::lookup(const std::string &name) const
{ {
Base::const_reverse_iterator it = FieldList::const_reverse_iterator it;
std::find(Base::rbegin(), Base::rend(), name); for ( it = m_fields.rbegin(); it != m_fields.rend(); ++it )
{
if ( (*it)->getName() == name )
return *it;
}
if ( it == Base::rend() ) throw TypeException( "", "field not found" );
throw TypeException( m_baseTypeName, name + ": field not found" ); }
return *it; /////////////////////////////////////////////////////////////////////////////////////
UdtFieldPtr &FieldCollection::lookup(ULONG index)
{
if (index >= m_fields.size() )
throw PyException( PyExc_IndexError, "index out of range" );
return m_fields[index];
}
/////////////////////////////////////////////////////////////////////////////////////
UdtFieldPtr &FieldCollection::lookup(const std::string &name)
{
FieldList::reverse_iterator it;
for ( it = m_fields.rbegin(); it != m_fields.rend(); ++it )
{
if ( (*it)->getName() == name )
return *it;
}
throw TypeException( "", "field not found" );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
ULONG getFieldOffsetRecirsive(TypeInfoPtr typeInfo, const std::string &fieldName) ULONG getFieldOffsetRecursive(TypeInfoPtr typeInfo, const std::string &fieldName)
{ {
// "m_field1.m_field2" -> ["m_field1", "m_field2"] // "m_field1.m_field2" -> ["m_field1", "m_field2"]
typedef boost::char_separator<char> CharSep; typedef boost::char_separator<char> CharSep;
@ -59,7 +84,10 @@ ULONG getFieldOffsetRecirsive(TypeInfoPtr typeInfo, const std::string &fieldName
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
} // namespace UdtUtils TypeInfoPtr SymbolUdtField::getTypeInfo()
{
return TypeInfo::getTypeInfo(m_symbol);
}
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////

View File

@ -6,64 +6,266 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "symengine.h"
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
namespace pykd { namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// class UdtField;
typedef boost::shared_ptr<UdtField> UdtFieldPtr;
class TypeInfo; class TypeInfo;
typedef boost::shared_ptr<TypeInfo> TypeInfoPtr; typedef boost::shared_ptr<TypeInfo> TypeInfoPtr;
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
namespace UdtUtils { class UdtField
{
/////////////////////////////////////////////////////////////////////////////////// public:
struct Field { const std::string& getName() const
Field( ULONG offset, const std::string &name, TypeInfoPtr type ) {
: m_offset(offset), m_name(name), m_type(type) return m_name;
{}
bool operator ==(const std::string &name) const {
return m_name == name;
} }
ULONG m_offset; const std::string& getVirtualBaseClassName() const
std::string m_name; {
TypeInfoPtr m_type; return m_virtualBaseName;
}
ULONG getOffset() const
{
return m_offset;
}
void setOffset( ULONG offset )
{
m_offset = offset;
}
bool isVirtualMember() const
{
return m_virtualMember;
}
bool isStaticMember() const
{
return m_staticMember;
}
ULONG64 getStaticOffset() const
{
return m_staticOffset;
}
void setStaticOffset( ULONG64 staticOffset)
{
m_staticMember = true;
m_staticOffset = staticOffset;
}
void getVirtualDisplacement( ULONG &virtualBasePtr, ULONG &virtualDispIndex, ULONG &virtualDispSize )
{
virtualBasePtr = m_virtualBasePtr;
virtualDispIndex = m_virtualDispIndex;
virtualDispSize = m_virtualDispSize;
}
void setVirtualDisplacement( ULONG virtualBasePtr, ULONG virtualDispIndex, ULONG virtualDispSize )
{
m_virtualMember = true;
m_virtualBasePtr = virtualBasePtr;
m_virtualDispIndex = virtualDispIndex;
m_virtualDispSize = virtualDispSize;
}
virtual TypeInfoPtr getTypeInfo() = 0;
protected:
UdtField( const std::string &name ) :
m_name( name ),
m_offset( 0 ),
m_virtualMember( false ),
m_staticMember( false ),
m_virtualBasePtr( 0 ),
m_virtualDispIndex( 0 ),
m_virtualDispSize( 0 )
{}
std::string m_name;
std::string m_virtualBaseName;
ULONG m_offset;
ULONG64 m_staticOffset;
bool m_staticMember;
bool m_virtualMember;
ULONG m_virtualBasePtr;
ULONG m_virtualDispIndex;
ULONG m_virtualDispSize;
}; };
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
class FieldCollection : public std::vector< Field > { class SymbolUdtField : public UdtField
typedef std::vector< Field > Base; {
public: public:
FieldCollection(const std::string &baseTypeName) : m_baseTypeName(baseTypeName)
{}
const Field &lookup(ULONG index) const; SymbolUdtField( const SymbolPtr &sym, const std::string& name ) :
const Field &lookup(const std::string &name) const; UdtField( name ),
m_symbol( sym )
{}
const std::string &getName() const { SymbolPtr& getSymbol() {
return m_baseTypeName; return m_symbol;
} }
private: private:
std::string m_baseTypeName;
virtual TypeInfoPtr getTypeInfo();
SymbolPtr m_symbol;
}; };
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
ULONG getFieldOffsetRecirsive(TypeInfoPtr typeInfo, const std::string &fieldName); class CustomUdtField : public UdtField
{
public:
CustomUdtField( const TypeInfoPtr &typeInfo, const std::string& name ) :
UdtField( name ),
m_type( typeInfo )
{}
private:
virtual TypeInfoPtr getTypeInfo() {
return m_type;
}
TypeInfoPtr m_type;
};
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
} // namespace UdtUtils class FieldCollection
{
public:
const UdtFieldPtr &lookup(ULONG index) const;
const UdtFieldPtr &lookup(const std::string &name) const;
UdtFieldPtr &lookup(ULONG index);
UdtFieldPtr &lookup(const std::string &name);
void push_back( const UdtFieldPtr& field ) {
m_fields.push_back( field );
}
ULONG count() const {
return static_cast<ULONG>( m_fields.size() );
}
private:
typedef std::vector<UdtFieldPtr> FieldList;
FieldList m_fields;
};
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
ULONG getFieldOffsetRecursive(TypeInfoPtr typeInfo, const std::string &fieldName);
///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
//
//namespace UdtUtils {
//
/////////////////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//
//
//
//struct Field {
//
// Field( ULONG offset, const std::string &name, SymbolPtr &symbol, SymbolPtr &baseVirtClass = SymbolPtr(),
// ULONG virtualBasePtr = 0, ULONG virtualDispIndex = 0, ULONG virtualDispSize = 0 ) :
// m_offset(offset),
// m_name(name),
// m_symbol(symbol),
// m_baseVirtClass( baseVirtClass ),
// m_virtualBasePtr( virtualBasePtr ),
// m_virtualDispIndex( virtualDispIndex ),
// m_virtualDispSize( virtualDispSize )
// {}
//
// bool operator ==(const std::string &name) const {
// return m_name == name;
// }
//
// ULONG m_offset;
// std::string m_name;
// SymbolPtr m_symbol;
// SymbolPtr m_baseVirtClass;
// ULONG m_virtualBasePtr;
// ULONG m_virtualDispIndex;
// ULONG m_virtualDispSize;
//};
//
/////////////////////////////////////////////////////////////////////////////////////
//
//class FieldCollection : public std::vector< Field > {
// typedef std::vector< Field > Base;
//public:
// FieldCollection(const std::string &baseTypeName) : m_baseTypeName(baseTypeName)
// {}
//
// const Field &lookup(ULONG index) const;
// const Field &lookup(const std::string &name) const;
//
// Field &lookup(ULONG index);
// Field &lookup(const std::string &name);
//
// const std::string &getName() const {
// return m_baseTypeName;
// }
//
//private:
// std::string m_baseTypeName;
//};
//
/////////////////////////////////////////////////////////////////////////////////////
//
//ULONG getFieldOffsetRecursive(TypeInfoPtr typeInfo, const std::string &fieldName);
//
/////////////////////////////////////////////////////////////////////////////////////
//
//} // namespace UdtUtils
//
/////////////////////////////////////////////////////////////////////////////////////
} // namespace pykd } // namespace pykd
///////////////////////////////////////////////////////////////////////////////////

View File

@ -6,21 +6,24 @@ import pykd
class CustomTypesTest(unittest.TestCase): class CustomTypesTest(unittest.TestCase):
def testCommonStruct(self): def testCommonStruct(self):
mySubStruct = pykd.createStruct("MySubCustomStruct")
mySubStruct.append( "m_uint1", pykd.typeInfo("UInt1B") )
mySubStruct.append( "m_uint2", pykd.typeInfo("UInt2B") )
mySubUnion = pykd.createUnion("MySubCustomUnion") tb = pykd.typeBuilder()
mySubUnion.append( "m_uint1", pykd.typeInfo("UInt1B") )
mySubUnion.append( "m_uint2", pykd.typeInfo("UInt2B") ) mySubStruct =tb.createStruct("MySubCustomStruct")
mySubStruct.append( "m_uint1", tb.UInt1B )
mySubStruct.append( "m_uint2", tb.UInt2B )
myType = pykd.createStruct("MyCustomStruct") mySubUnion = tb.createUnion("MySubCustomUnion")
myType.append( "m_uint1", pykd.typeInfo("UInt1B") ) mySubUnion.append( "m_uint1", tb.UInt1B )
myType.append( "m_uint4", pykd.typeInfo("UInt4B") ) mySubUnion.append( "m_uint2", tb.UInt2B )
myType.append( "m_uint2", pykd.typeInfo("UInt2B") )
myType = tb.createStruct("MyCustomStruct")
myType.append( "m_uint1", tb.UInt1B )
myType.append( "m_uint4", tb.UInt4B )
myType.append( "m_uint2", tb.UInt2B )
myType.append( "m_struct", mySubStruct ) myType.append( "m_struct", mySubStruct )
myType.append( "m_union", mySubUnion ) myType.append( "m_union", mySubUnion )
myType.append( "m_uint8", pykd.typeInfo("UInt8B") ) myType.append( "m_uint8", tb.UInt8B )
self.assertTrue( myType.size() != 0 ) self.assertTrue( myType.size() != 0 )
self.assertTrue( myType.size() >= myType.fieldOffset("m_uint8") + myType.m_uint8.size() ) self.assertTrue( myType.size() >= myType.fieldOffset("m_uint8") + myType.m_uint8.size() )
@ -42,10 +45,13 @@ class CustomTypesTest(unittest.TestCase):
# print myType # print myType
def testCommonUnion(self): def testCommonUnion(self):
myType = pykd.createUnion("MyCustomStruct")
myType.append( "m_uint1", pykd.typeInfo("UInt1B") ) tb = pykd.typeBuilder()
myType.append( "m_uint4", pykd.typeInfo("UInt4B") )
myType.append( "m_uint2", pykd.typeInfo("UInt2B") ) myType = tb.createUnion("MyCustomStruct")
myType.append( "m_uint1", tb.UInt1B )
myType.append( "m_uint4", tb.UInt4B )
myType.append( "m_uint2", tb.UInt2B )
self.assertFalse( myType.size() == 0 ) self.assertFalse( myType.size() == 0 )
self.assertTrue( myType.fieldOffset("m_uint1") == 0 ) self.assertTrue( myType.fieldOffset("m_uint1") == 0 )
@ -53,20 +59,23 @@ class CustomTypesTest(unittest.TestCase):
self.assertTrue( myType.fieldOffset("m_uint2") == 0 ) self.assertTrue( myType.fieldOffset("m_uint2") == 0 )
def testDupFieldName(self): def testDupFieldName(self):
myType = pykd.createStruct("MyCustomStruct")
tb = pykd.typeBuilder()
myType = tb.createStruct("MyCustomStruct")
exceptionRised = False exceptionRised = False
myType.append( "m_uint1", pykd.typeInfo("UInt1B") ) myType.append( "m_uint1", tb.UInt1B )
try: try:
myType.append( "m_uint1", pykd.typeInfo("UInt1B") ) myType.append( "m_uint1", tb.UInt1B )
except pykd.TypeException: except pykd.TypeException:
exceptionRised = True exceptionRised = True
self.assertTrue(exceptionRised) self.assertTrue(exceptionRised)
myType = pykd.createUnion("MyCustomStruct") myType = tb.createUnion("MyCustomStruct")
exceptionRised = False exceptionRised = False
myType.append( "m_uint1", pykd.typeInfo("UInt1B") ) myType.append( "m_uint1", tb.UInt1B )
try: try:
myType.append( "m_uint1", pykd.typeInfo("UInt1B") ) myType.append( "m_uint1", tb.UInt1B )
except pykd.TypeException: except pykd.TypeException:
exceptionRised = True exceptionRised = True
self.assertTrue(exceptionRised) self.assertTrue(exceptionRised)

View File

@ -69,7 +69,7 @@ class ModuleTest( unittest.TestCase ):
self.assertTrue( re.search('targetapp\\.cpp', fileName ) ) self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
self.assertEqual( 2, displacement ) self.assertEqual( 2, displacement )
fileName, lineNo, displacement = pykd.getSourceLine() fileName, lineNo, displacement = pykd.getSourceLine()
self.assertEqual( 644, lineNo ) self.assertEqual( 653, lineNo )
def testEnumSymbols( self ): def testEnumSymbols( self ):
lst = target.module.enumSymbols() lst = target.module.enumSymbols()

View File

@ -41,11 +41,10 @@ class TypedVarTest( unittest.TestCase ):
target.module.offset("g_structTestPtr") ) target.module.offset("g_structTestPtr") )
self.assertEqual( 500, tvDiaStruct.deref().m_field1 ) self.assertEqual( 500, tvDiaStruct.deref().m_field1 )
customStructTest = pykd.createStruct("customStructTest") customStructTest = pykd.typeBuilder().createStruct("customStructTest", 4)
customStructTest.append("m_field0", pykd.typeInfo("UInt4B")) customStructTest.append("m_field0", pykd.typeInfo("UInt4B"))
customStructTest.append("m_field1", pykd.typeInfo("UInt8B")) customStructTest.append("m_field1", pykd.typeInfo("UInt8B"))
tvCustomStruct = pykd.typedVar( customStructTest.ptrTo(), tvCustomStruct = pykd.typedVar( customStructTest.ptrTo(), target.module.offset("g_structTestPtr") )
target.module.offset("g_structTestPtr") )
self.assertEqual( 500, tvCustomStruct.deref().m_field1 ) self.assertEqual( 500, tvCustomStruct.deref().m_field1 )
def testConst(self): def testConst(self):

View File

@ -109,7 +109,6 @@ class TypeInfoTest( unittest.TestCase ):
ti2 = target.module.type( "struct2" ) ti2 = target.module.type( "struct2" )
self.assertTrue( ti2.fieldOffset("m_union") >= ti2.m_struct.size() ) self.assertTrue( ti2.fieldOffset("m_union") >= ti2.m_struct.size() )
self.assertEqual( ti2.fieldOffset("m_union"), ti2.fieldOffset("m_union.m_value") )
self.assertEqual( 0, ti2.m_union.fieldOffset("m_value") ) self.assertEqual( 0, ti2.m_union.fieldOffset("m_value") )
def testSize( self ): def testSize( self ):
@ -199,10 +198,14 @@ class TypeInfoTest( unittest.TestCase ):
def testStaticField(self): def testStaticField(self):
ti = pykd.typeInfo( "g_classChild" ) ti = pykd.typeInfo( "g_classChild" )
self.assertNotEqual( 0, ti.m_staticField.staticOffset() ) self.assertNotEqual( 0, ti.staticOffset( "m_staticField" ) )
if not ti.m_staticConst.staticOffset(): self.assertNotEqual( 0, ti.staticOffset("m_stdstr") )
if not ti.staticOffset("m_staticConst"):
self.assertFalse( "MS DIA bug: https://connect.microsoft.com/VisualStudio/feedback/details/737430" ) self.assertFalse( "MS DIA bug: https://connect.microsoft.com/VisualStudio/feedback/details/737430" )
self.assertNotEqual( 0, ti.m_stdstr.staticOffset() )
def testVfnTable(self):
ti = pykd.typeInfo( "g_classChild" )
self.assertTrue( hasattr( ti, "__VFN_table" ) )
def testUdtSubscribe(self): def testUdtSubscribe(self):
ti = pykd.typeInfo( "g_virtChild" ) ti = pykd.typeInfo( "g_virtChild" )
@ -214,3 +217,8 @@ class TypeInfoTest( unittest.TestCase ):
ti = target.module.type("structNullSize") ti = target.module.type("structNullSize")
self.assertEqual( 0, len(ti) ) self.assertEqual( 0, len(ti) )
def testDerefName(self):
entry = pykd.typedVar("entry1").Flink
self.assertEqual( "_LIST_ENTRY*", entry.type().name() )