mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[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:
parent
9b4260f5f3
commit
18392dca83
@ -1,22 +1,30 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "customtypes.h"
|
||||
#include "dbgexcept.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace pykd {
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CustomTypeBase::CustomTypeBase(const std::string &name, ULONG pointerSize)
|
||||
: UdtFieldColl(name)
|
||||
TypeInfoPtr TypeBuilder::createStruct( const std::string &name, ULONG align )
|
||||
{
|
||||
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;
|
||||
try
|
||||
@ -24,29 +32,22 @@ void CustomTypeBase::throwIfFiledExist(const std::string &fieldName)
|
||||
lookupField(fieldName);
|
||||
fieldExist = true;
|
||||
}
|
||||
catch (const TypeException &except)
|
||||
catch (const TypeException&)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
}
|
||||
|
||||
if (fieldExist)
|
||||
throw TypeException(getName(), "duplicate field name: " + fieldName);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CustomTypeBase::throwIfTypeRecursive(TypeInfoPtr type)
|
||||
void CustomBase::throwIfTypeRecursive(TypeInfoPtr type)
|
||||
{
|
||||
if (type->is(this))
|
||||
throw TypeException(getName(), "wrong type of field");
|
||||
throw TypeException(getName(), "recursive type definition");
|
||||
|
||||
return throwIfTypeRecursiveImpl(type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CustomTypeBase::throwIfTypeRecursiveImpl(TypeInfoPtr type)
|
||||
{
|
||||
if (type->isEnum())
|
||||
if ( !type->isUserDefined() )
|
||||
return;
|
||||
|
||||
try
|
||||
@ -58,7 +59,7 @@ void CustomTypeBase::throwIfTypeRecursiveImpl(TypeInfoPtr type)
|
||||
if (fileldType->is(this))
|
||||
throw TypeException(getName(), "wrong type of field");
|
||||
|
||||
throwIfTypeRecursiveImpl(fileldType);
|
||||
throwIfTypeRecursive(fileldType);
|
||||
}
|
||||
}
|
||||
catch (const TypeException &except)
|
||||
@ -69,78 +70,188 @@ void CustomTypeBase::throwIfTypeRecursiveImpl(TypeInfoPtr type)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypeInfoPtr CustomStruct::create(
|
||||
const std::string &name,
|
||||
ULONG alignReq /*= 0*/,
|
||||
ULONG pointerSize /*= 0*/)
|
||||
void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr &fieldType )
|
||||
{
|
||||
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())
|
||||
return 0;
|
||||
throwIfFiledExist(fieldName);
|
||||
throwIfTypeRecursive(fieldType);
|
||||
|
||||
UdtUtils::Field &field = Base::last();
|
||||
return field.m_offset + field.m_type->getSize();
|
||||
CustomUdtField *field = new CustomUdtField( fieldType, fieldName );
|
||||
|
||||
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()
|
||||
{
|
||||
return TypeInfoPtr( new PointerTypeInfo(ptrSize()) );
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//CustomTypeBase::CustomTypeBase(const std::string &name, ULONG pointerSize)
|
||||
// : UdtFieldColl(name)
|
||||
//{
|
||||
// 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()) );
|
||||
//}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -4,90 +4,217 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "typeinfo.h"
|
||||
#include "win\dbgeng.h"
|
||||
#include "dbgengine.h"
|
||||
#include <string>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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:
|
||||
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 throwIfTypeRecursive(TypeInfoPtr type);
|
||||
|
||||
private:
|
||||
void throwIfTypeRecursiveImpl(TypeInfoPtr type);
|
||||
};
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CustomStruct : public CustomTypeBase
|
||||
{
|
||||
typedef CustomTypeBase Base;
|
||||
public:
|
||||
static TypeInfoPtr create(const std::string &name, ULONG align = 0, ULONG pointerSize = 0);
|
||||
virtual ULONG getSize() {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
ULONG m_ptrSize;
|
||||
|
||||
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 {
|
||||
return "custom struct";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
ULONG m_align;
|
||||
ULONG m_size;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CustomUnion : public CustomTypeBase
|
||||
class CustomStruct : public CustomBase
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
CustomStruct( const std::string &name, ULONG ptrSize, ULONG align ) :
|
||||
CustomBase( name, ptrSize, align )
|
||||
{}
|
||||
|
||||
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
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "disasm.h"
|
||||
#include "stkframe.h"
|
||||
#include "bpoint.h"
|
||||
#include "eventhandler.h"
|
||||
|
||||
#include "win/dbgio.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( 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_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_enumTypes, Module::enumTypes, 0, 1 );
|
||||
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( "appendSymbolPath", &appendSymbolPath, "Append current symbol path");
|
||||
|
||||
// custom types
|
||||
python::def( "createStruct", &CustomStruct::create, CustomStruct_create( python::args( "name", "align", "ptrSize" ),
|
||||
"Create empty structure. Use append() method for building" ) );
|
||||
python::def( "createUnion", &CustomUnion::create, CustomUnion_create( python::args( "name", "ptrSize" ),
|
||||
"Create empty union. Use append() method for building" ) );
|
||||
python::def( "pVoid", &PtrToVoid, "Create \"Void*\" type" );
|
||||
//// custom types
|
||||
//python::def( "createStruct", &CustomStruct::create, CustomStruct_create( python::args( "name", "align", "ptrSize" ),
|
||||
// "Create empty structure. Use append() method for building" ) );
|
||||
//python::def( "createUnion", &CustomUnion::create, CustomUnion_create( python::args( "name", "ptrSize" ),
|
||||
// "Create empty union. Use append() method for building" ) );
|
||||
//python::def( "pVoid", &PtrToVoid, "Create \"Void*\" type" );
|
||||
|
||||
python::class_<intBase>( "intBase", "intBase", python::no_init )
|
||||
.def( python::init<python::object&>() )
|
||||
@ -393,8 +394,8 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
.def("__init__", python::make_constructor(TypeInfo::getTypeInfoByName ) )
|
||||
.def( "name", &TypeInfo::getName )
|
||||
.def( "size", &TypeInfo::getSize )
|
||||
.def( "staticOffset", &TypeInfo::getStaticOffset )
|
||||
.def( "fieldOffset", &TypeInfo::getFieldOffsetByNameRecirsive )
|
||||
.def( "staticOffset", &TypeInfo::getStaticOffsetByName )
|
||||
.def( "fieldOffset", &TypeInfo::getFieldOffsetByNameRecursive )
|
||||
.def( "bitOffset", &TypeInfo::getBitOffset )
|
||||
.def( "bitWidth", &TypeInfo::getBitWidth )
|
||||
.def( "field", &TypeInfo::getField )
|
||||
@ -416,7 +417,7 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Return virtual address" )
|
||||
.def("sizeof", &TypedVar::getSize,
|
||||
"Return size of a variable in the target memory" )
|
||||
.def("fieldOffset", &TypedVar::getFieldOffsetByNameRecirsive,
|
||||
.def("fieldOffset", &TypedVar::getFieldOffsetByNameRecursive,
|
||||
"Return target field offset" )
|
||||
.def("field", &TypedVar::getField,
|
||||
"Return field of structure as an object attribute" )
|
||||
@ -433,6 +434,29 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
.def("__getitem__", &TypedVar::getElementByIndex )
|
||||
.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> >(
|
||||
"cpuReg", "CPU regsiter class", boost::python::no_init )
|
||||
.def( "name", &CpuReg::name, "The name of the regsiter" )
|
||||
|
@ -265,21 +265,23 @@ UdtTypedVar::getField( const std::string &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");
|
||||
|
||||
return TypedVar::getTypedVar( fieldType, VarDataMemory::factory(fieldType->getStaticOffset() ) );
|
||||
return TypedVar::getTypedVar( fieldType, VarDataMemory::factory(staticOffset) );
|
||||
}
|
||||
|
||||
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) );
|
||||
@ -290,23 +292,27 @@ UdtTypedVar::getField( const std::string &fieldName )
|
||||
python::object
|
||||
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");
|
||||
|
||||
return python::make_tuple(
|
||||
return python::make_tuple(
|
||||
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(
|
||||
@ -316,12 +322,30 @@ UdtTypedVar::getElementByIndex( ULONG index )
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LONG UdtTypedVar::getVirtualBaseDisplacement( TypeInfoPtr& typeInfo )
|
||||
LONG UdtTypedVar::getVirtualBaseDisplacement( const std::string &fieldName )
|
||||
{
|
||||
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);
|
||||
|
||||
@ -345,21 +369,23 @@ std::string UdtTypedVar::print()
|
||||
TypeInfoPtr fieldType = m_typeInfo->getFieldByIndex(i);
|
||||
TypedVarPtr fieldVar;
|
||||
|
||||
if ( fieldType->isStaticMember() )
|
||||
if ( m_typeInfo->isStaticMemberByIndex(i) )
|
||||
{
|
||||
if ( fieldType->getStaticOffset() != 0 )
|
||||
fieldVar = TypedVar::getTypedVar( fieldType, VarDataMemory::factory( fieldType->getStaticOffset() ) );
|
||||
ULONG64 staticOffset = m_typeInfo->getStaticOffsetByIndex(i);
|
||||
|
||||
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) << ':';
|
||||
}
|
||||
else
|
||||
{
|
||||
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) );
|
||||
@ -514,7 +540,7 @@ TypedVarPtr containingRecordByType( ULONG64 addr, const TypeInfoPtr &typeInfo, c
|
||||
{
|
||||
addr = addr64(addr);
|
||||
|
||||
VarDataPtr varData = VarDataMemory::factory( addr - typeInfo->getFieldOffsetByNameRecirsive(fieldName) );
|
||||
VarDataPtr varData = VarDataMemory::factory( addr - typeInfo->getFieldOffsetByNameRecursive(fieldName) );
|
||||
|
||||
return TypedVar::getTypedVar( typeInfo, varData );
|
||||
}
|
||||
@ -549,7 +575,7 @@ python::list getTypedVarListByType( ULONG64 listHeadAddress, const TypeInfoPtr &
|
||||
|
||||
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 ) );
|
||||
}
|
||||
else
|
||||
|
@ -34,8 +34,8 @@ public:
|
||||
return m_size;
|
||||
}
|
||||
|
||||
ULONG getFieldOffsetByNameRecirsive(const std::string &fieldName) {
|
||||
return m_typeInfo->getFieldOffsetByNameRecirsive(fieldName);
|
||||
ULONG getFieldOffsetByNameRecursive(const std::string &fieldName) {
|
||||
return m_typeInfo->getFieldOffsetByNameRecursive(fieldName);
|
||||
}
|
||||
|
||||
TypeInfoPtr
|
||||
@ -87,6 +87,9 @@ protected:
|
||||
|
||||
TypedVar ( const TypeInfoPtr& typeInfo, VarDataPtr varData );
|
||||
|
||||
virtual ~TypedVar()
|
||||
{}
|
||||
|
||||
TypeInfoPtr m_typeInfo;
|
||||
|
||||
VarDataPtr m_varData;
|
||||
@ -171,12 +174,13 @@ protected:
|
||||
virtual TypedVarPtr getField( const std::string &fieldName );
|
||||
|
||||
virtual ULONG getElementCount() {
|
||||
return m_typeInfo->getFieldCount();
|
||||
return m_typeInfo->getFieldCount();
|
||||
}
|
||||
|
||||
virtual python::object getElementByIndex( ULONG index );
|
||||
|
||||
LONG getVirtualBaseDisplacement( TypeInfoPtr& typeInfo );
|
||||
LONG getVirtualBaseDisplacement( const std::string &fieldName );
|
||||
LONG getVirtualBaseDisplacementByIndex( ULONG index );
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -609,51 +609,39 @@ TypeInfoPtr TypeInfo::ptrTo()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG64 TypeInfo::getStaticOffset()
|
||||
{
|
||||
if ( !m_staticMember )
|
||||
throw TypeException( getName(), "This is not a static member" );
|
||||
|
||||
return m_staticOffset;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string UdtFieldColl::print()
|
||||
std::string UdtTypeInfoBase::print()
|
||||
{
|
||||
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();
|
||||
|
||||
for ( ULONG i = 0; i < fieldCount; ++i )
|
||||
{
|
||||
const UdtUtils::Field &udtField = lookupField(i);
|
||||
TypeInfoPtr fieldType = udtField.m_type;
|
||||
UdtFieldPtr& udtField = lookupField(i);
|
||||
|
||||
if ( fieldType->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() )
|
||||
if ( udtField->isStaticMember() )
|
||||
{
|
||||
ULONG virtualBasePtr, virtualDispIndex, virtualDispSize;
|
||||
fieldType->getVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
|
||||
|
||||
sstr << " virtual base " << fieldType->getVirtualBase()->getName();
|
||||
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << udtField.m_offset;
|
||||
sstr << " " << udtField.m_name << ':';
|
||||
sstr << " =" << std::right << std::setw(10) << std::setfill('0') << std::hex << udtField->getStaticOffset();
|
||||
sstr << " " << std::left << std::setw(18) << std::setfill(' ') << udtField->getName() << ':';
|
||||
}
|
||||
else
|
||||
{
|
||||
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << udtField.m_offset;
|
||||
sstr << " " << std::left << std::setw(24) << std::setfill(' ') << udtField.m_name << ':';
|
||||
if ( udtField->isVirtualMember() )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -662,14 +650,40 @@ std::string UdtFieldColl::print()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG UdtFieldColl::getAlignReq()
|
||||
ULONG UdtTypeInfoBase::getAlignReq()
|
||||
{
|
||||
ULONG alignReq = 1;
|
||||
const ULONG fieldCount = getFieldCount();
|
||||
for ( ULONG i = 0; i < fieldCount; ++i )
|
||||
alignReq = max(alignReq, lookupField(i).m_type->getAlignReq());
|
||||
//ULONG alignReq = 1;
|
||||
//const ULONG fieldCount = getFieldCount();
|
||||
//for ( ULONG i = 0; i < fieldCount; ++i )
|
||||
// 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
|
||||
if ( symTag == SymTagData )
|
||||
{
|
||||
TypeInfoPtr ti = TypeInfo::getTypeInfo( childSym );
|
||||
SymbolUdtField *fieldPtr = new SymbolUdtField( childSym, childSym->getName() );
|
||||
|
||||
ULONG fieldOffset = 0;
|
||||
switch ( childSym->getDataKind() )
|
||||
{
|
||||
case DataIsMember:
|
||||
|
||||
if ( baseVirtualSym )
|
||||
{
|
||||
ti->setVirtualBase(
|
||||
TypeInfo::getTypeInfo(baseVirtualSym),
|
||||
virtualBasePtr,
|
||||
virtualDispIndex,
|
||||
virtualDispSize );
|
||||
}
|
||||
|
||||
fieldOffset = startOffset + childSym->getOffset();
|
||||
fieldPtr->setOffset( startOffset + childSym->getOffset() );
|
||||
break;
|
||||
|
||||
case DataIsStaticMember:
|
||||
ti->setStaticOffset( childSym->getVa() );
|
||||
fieldPtr->setStaticOffset( childSym->getVa() );
|
||||
break;
|
||||
}
|
||||
|
||||
UdtFieldColl::push_back(
|
||||
UdtUtils::Field( fieldOffset, childSym->getName(), ti )
|
||||
);
|
||||
if ( baseVirtualSym )
|
||||
fieldPtr->setVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
|
||||
|
||||
m_fields.push_back( UdtFieldPtr( fieldPtr ) );
|
||||
}
|
||||
else
|
||||
if ( symTag == SymTagVTable )
|
||||
{
|
||||
TypeInfoPtr ti = TypeInfo::getTypeInfo( childSym );
|
||||
SymbolUdtField *fieldPtr = new SymbolUdtField( childSym, "__VFN_table" );
|
||||
|
||||
fieldPtr->setOffset( startOffset + childSym->getOffset() );
|
||||
|
||||
if ( baseVirtualSym )
|
||||
{
|
||||
ti->setVirtualBase(
|
||||
TypeInfo::getTypeInfo(baseVirtualSym),
|
||||
virtualBasePtr,
|
||||
virtualDispIndex,
|
||||
virtualDispSize );
|
||||
|
||||
}
|
||||
fieldPtr->setVirtualDisplacement( virtualBasePtr, virtualDispIndex, virtualDispSize );
|
||||
|
||||
UdtFieldColl::push_back(
|
||||
UdtUtils::Field( startOffset + childSym->getOffset(), "__VFN_table", ti )
|
||||
);
|
||||
m_fields.push_back( UdtFieldPtr( fieldPtr ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -777,11 +773,8 @@ void UdtTypeInfo::getVirtualFields()
|
||||
|
||||
void UdtTypeInfo::refreshFields()
|
||||
{
|
||||
if ( UdtFieldColl::empty() )
|
||||
{
|
||||
getFields( m_dia, SymbolPtr() );
|
||||
getVirtualFields();
|
||||
}
|
||||
getFields( m_dia, SymbolPtr() );
|
||||
getVirtualFields();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
213
pykd/typeinfo.h
213
pykd/typeinfo.h
@ -52,16 +52,13 @@ public:
|
||||
public:
|
||||
|
||||
TypeInfo() :
|
||||
m_staticOffset( 0 ),
|
||||
m_constant( false ),
|
||||
m_staticMember( false ),
|
||||
m_virtualMember( false ),
|
||||
m_virtualBasePtr( 0 ),
|
||||
m_virtualDispIndex( 0 ),
|
||||
m_virtualDispSize( 0 ),
|
||||
m_ptrSize( 0 )
|
||||
{}
|
||||
|
||||
virtual ~TypeInfo()
|
||||
{}
|
||||
|
||||
virtual std::string print() {
|
||||
std::stringstream sstr;
|
||||
sstr << "Type name: " << getName();
|
||||
@ -85,7 +82,7 @@ public:
|
||||
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" );
|
||||
}
|
||||
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
|
||||
@ -100,6 +97,46 @@ public:
|
||||
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 bool isBasicType() {
|
||||
@ -158,8 +195,8 @@ public:
|
||||
throw PyException( PyExc_TypeError, "object is unsubscriptable");
|
||||
}
|
||||
|
||||
virtual void appendField(const std::string &fieldName, TypeInfoPtr fieldType) {
|
||||
throw TypeException( getName(), "type is not is not extensible" );
|
||||
virtual void appendField(const std::string &fieldName, TypeInfoPtr &fieldType) {
|
||||
throw TypeException( getName(), "type is not is not editable" );
|
||||
}
|
||||
|
||||
TypeInfoPtr ptrTo();
|
||||
@ -178,42 +215,6 @@ public:
|
||||
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 {
|
||||
return this == rhs;
|
||||
}
|
||||
@ -232,24 +233,10 @@ protected:
|
||||
static
|
||||
TypeInfoPtr getRecurciveComplexType( TypeInfoPtr &lowestType, std::string &suffix, ULONG ptrSize );
|
||||
|
||||
ULONG64 m_staticOffset;
|
||||
|
||||
bool m_constant;
|
||||
|
||||
bool m_staticMember;
|
||||
|
||||
bool m_virtualMember;
|
||||
|
||||
BaseTypeVariant m_constantValue;
|
||||
|
||||
LONG m_virtualBasePtr;
|
||||
|
||||
ULONG m_virtualDispIndex;
|
||||
|
||||
ULONG m_virtualDispSize;
|
||||
|
||||
TypeInfoPtr m_virtualBaseType;
|
||||
|
||||
ULONG m_ptrSize;
|
||||
};
|
||||
|
||||
@ -323,40 +310,60 @@ private:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class UdtFieldColl : public TypeInfo
|
||||
class UdtTypeInfoBase : public TypeInfo
|
||||
{
|
||||
protected:
|
||||
virtual std::string getName() {
|
||||
return m_fields.getName();
|
||||
return m_name;
|
||||
}
|
||||
|
||||
virtual TypeInfoPtr getField( const std::string &fieldName ) {
|
||||
return lookupField(fieldName).m_type;
|
||||
return lookupField(fieldName)->getTypeInfo();
|
||||
}
|
||||
|
||||
virtual TypeInfoPtr getFieldByIndex( ULONG index ) {
|
||||
return lookupField(index).m_type;
|
||||
return lookupField(index)->getTypeInfo();
|
||||
}
|
||||
|
||||
virtual std::string getFieldNameByIndex( ULONG index ) {
|
||||
return lookupField(index).m_name;
|
||||
return lookupField(index)->getName();
|
||||
}
|
||||
|
||||
virtual ULONG getFieldOffsetByNameRecirsive( const std::string &fieldName ) {
|
||||
return UdtUtils::getFieldOffsetRecirsive( shared_from_this(), fieldName );
|
||||
virtual ULONG getFieldOffsetByNameRecursive( const std::string &fieldName ) {
|
||||
return getFieldOffsetRecursive( shared_from_this(), fieldName );
|
||||
}
|
||||
|
||||
virtual ULONG getFieldOffsetByNameNotRecursively( const std::string &fieldName ) {
|
||||
return lookupField(fieldName).m_offset;
|
||||
return lookupField(fieldName)->getOffset();
|
||||
}
|
||||
|
||||
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() {
|
||||
refreshFields();
|
||||
return (ULONG)m_fields.size();
|
||||
if ( !m_fieldsGot )
|
||||
{
|
||||
refreshFields();
|
||||
m_fieldsGot = true;
|
||||
}
|
||||
return m_fields.count();
|
||||
}
|
||||
|
||||
virtual ULONG getElementCount() {
|
||||
@ -375,42 +382,70 @@ protected:
|
||||
|
||||
virtual ULONG getAlignReq() override;
|
||||
|
||||
protected:
|
||||
UdtFieldColl(const std::string &typeName) : m_fields(typeName) {}
|
||||
|
||||
virtual void refreshFields() {}
|
||||
virtual std::string getTypeString() const = 0;
|
||||
|
||||
bool empty() const {
|
||||
return m_fields.empty();
|
||||
virtual bool isVirtualMember( const std::string& fieldName )
|
||||
{
|
||||
return lookupField(fieldName)->isVirtualMember();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const UdtUtils::Field &lookupField( T index) {
|
||||
refreshFields();
|
||||
const UdtFieldPtr &lookupField( T index)const {
|
||||
if ( !m_fieldsGot )
|
||||
{
|
||||
refreshFields();
|
||||
m_fieldsGot = true;
|
||||
}
|
||||
return m_fields.lookup(index);
|
||||
}
|
||||
|
||||
UdtUtils::Field &last(){
|
||||
return *m_fields.rbegin();
|
||||
template <typename T>
|
||||
UdtFieldPtr &lookupField( T index) {
|
||||
if ( !m_fieldsGot )
|
||||
{
|
||||
refreshFields();
|
||||
m_fieldsGot = true;
|
||||
}
|
||||
return m_fields.lookup(index);
|
||||
}
|
||||
|
||||
private:
|
||||
UdtUtils::FieldCollection m_fields;
|
||||
protected:
|
||||
|
||||
bool m_fieldsGot;
|
||||
|
||||
FieldCollection m_fields;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class UdtTypeInfo : public UdtFieldColl
|
||||
class UdtTypeInfo : public UdtTypeInfoBase
|
||||
{
|
||||
public:
|
||||
|
||||
UdtTypeInfo (SymbolPtr &symbol ) :
|
||||
UdtFieldColl( symbol->getName() ),
|
||||
UdtTypeInfoBase( symbol->getName() ),
|
||||
m_dia( symbol )
|
||||
{
|
||||
}
|
||||
@ -423,10 +458,6 @@ protected:
|
||||
|
||||
virtual void refreshFields() override;
|
||||
|
||||
virtual std::string getTypeString() const override {
|
||||
return "struct/class";
|
||||
}
|
||||
|
||||
void getFields(
|
||||
SymbolPtr &rootSym,
|
||||
SymbolPtr &baseVirtualSym,
|
||||
|
@ -10,33 +10,58 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace pykd {
|
||||
namespace UdtUtils {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const Field &FieldCollection::lookup(ULONG index) const
|
||||
const UdtFieldPtr& FieldCollection::lookup(ULONG index) const
|
||||
{
|
||||
if (index >= Base::size())
|
||||
throw PyException( PyExc_IndexError, m_baseTypeName + " index out of range" );
|
||||
return at(index);
|
||||
if (index >= m_fields.size() )
|
||||
throw PyException( PyExc_IndexError, "index out of range" );
|
||||
|
||||
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 =
|
||||
std::find(Base::rbegin(), Base::rend(), name);
|
||||
FieldList::const_reverse_iterator it;
|
||||
for ( it = m_fields.rbegin(); it != m_fields.rend(); ++it )
|
||||
{
|
||||
if ( (*it)->getName() == name )
|
||||
return *it;
|
||||
}
|
||||
|
||||
if ( it == Base::rend() )
|
||||
throw TypeException( m_baseTypeName, name + ": field not found" );
|
||||
throw TypeException( "", "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"]
|
||||
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);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
254
pykd/udtutils.h
254
pykd/udtutils.h
@ -6,64 +6,266 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "symengine.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace pykd {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
class UdtField;
|
||||
typedef boost::shared_ptr<UdtField> UdtFieldPtr;
|
||||
|
||||
class TypeInfo;
|
||||
typedef boost::shared_ptr<TypeInfo> TypeInfoPtr;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace UdtUtils {
|
||||
class UdtField
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
|
||||
struct Field {
|
||||
Field( ULONG offset, const std::string &name, TypeInfoPtr type )
|
||||
: m_offset(offset), m_name(name), m_type(type)
|
||||
{}
|
||||
|
||||
bool operator ==(const std::string &name) const {
|
||||
return m_name == name;
|
||||
const std::string& getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
ULONG m_offset;
|
||||
std::string m_name;
|
||||
TypeInfoPtr m_type;
|
||||
const std::string& getVirtualBaseClassName() const
|
||||
{
|
||||
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 > {
|
||||
typedef std::vector< Field > Base;
|
||||
class SymbolUdtField : public UdtField
|
||||
{
|
||||
public:
|
||||
FieldCollection(const std::string &baseTypeName) : m_baseTypeName(baseTypeName)
|
||||
{}
|
||||
|
||||
const Field &lookup(ULONG index) const;
|
||||
const Field &lookup(const std::string &name) const;
|
||||
SymbolUdtField( const SymbolPtr &sym, const std::string& name ) :
|
||||
UdtField( name ),
|
||||
m_symbol( sym )
|
||||
{}
|
||||
|
||||
const std::string &getName() const {
|
||||
return m_baseTypeName;
|
||||
SymbolPtr& getSymbol() {
|
||||
return m_symbol;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -6,21 +6,24 @@ import pykd
|
||||
|
||||
class CustomTypesTest(unittest.TestCase):
|
||||
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")
|
||||
mySubUnion.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
mySubUnion.append( "m_uint2", pykd.typeInfo("UInt2B") )
|
||||
tb = pykd.typeBuilder()
|
||||
|
||||
mySubStruct =tb.createStruct("MySubCustomStruct")
|
||||
mySubStruct.append( "m_uint1", tb.UInt1B )
|
||||
mySubStruct.append( "m_uint2", tb.UInt2B )
|
||||
|
||||
myType = pykd.createStruct("MyCustomStruct")
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
myType.append( "m_uint4", pykd.typeInfo("UInt4B") )
|
||||
myType.append( "m_uint2", pykd.typeInfo("UInt2B") )
|
||||
mySubUnion = tb.createUnion("MySubCustomUnion")
|
||||
mySubUnion.append( "m_uint1", tb.UInt1B )
|
||||
mySubUnion.append( "m_uint2", tb.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_union", mySubUnion )
|
||||
myType.append( "m_uint8", pykd.typeInfo("UInt8B") )
|
||||
myType.append( "m_uint8", tb.UInt8B )
|
||||
|
||||
self.assertTrue( myType.size() != 0 )
|
||||
self.assertTrue( myType.size() >= myType.fieldOffset("m_uint8") + myType.m_uint8.size() )
|
||||
@ -42,10 +45,13 @@ class CustomTypesTest(unittest.TestCase):
|
||||
# print myType
|
||||
|
||||
def testCommonUnion(self):
|
||||
myType = pykd.createUnion("MyCustomStruct")
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
myType.append( "m_uint4", pykd.typeInfo("UInt4B") )
|
||||
myType.append( "m_uint2", pykd.typeInfo("UInt2B") )
|
||||
|
||||
tb = pykd.typeBuilder()
|
||||
|
||||
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.assertTrue( myType.fieldOffset("m_uint1") == 0 )
|
||||
@ -53,20 +59,23 @@ class CustomTypesTest(unittest.TestCase):
|
||||
self.assertTrue( myType.fieldOffset("m_uint2") == 0 )
|
||||
|
||||
def testDupFieldName(self):
|
||||
myType = pykd.createStruct("MyCustomStruct")
|
||||
|
||||
tb = pykd.typeBuilder()
|
||||
|
||||
myType = tb.createStruct("MyCustomStruct")
|
||||
exceptionRised = False
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
myType.append( "m_uint1", tb.UInt1B )
|
||||
try:
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
myType.append( "m_uint1", tb.UInt1B )
|
||||
except pykd.TypeException:
|
||||
exceptionRised = True
|
||||
self.assertTrue(exceptionRised)
|
||||
|
||||
myType = pykd.createUnion("MyCustomStruct")
|
||||
myType = tb.createUnion("MyCustomStruct")
|
||||
exceptionRised = False
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
myType.append( "m_uint1", tb.UInt1B )
|
||||
try:
|
||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
||||
myType.append( "m_uint1", tb.UInt1B )
|
||||
except pykd.TypeException:
|
||||
exceptionRised = True
|
||||
self.assertTrue(exceptionRised)
|
||||
|
@ -69,7 +69,7 @@ class ModuleTest( unittest.TestCase ):
|
||||
self.assertTrue( re.search('targetapp\\.cpp', fileName ) )
|
||||
self.assertEqual( 2, displacement )
|
||||
fileName, lineNo, displacement = pykd.getSourceLine()
|
||||
self.assertEqual( 644, lineNo )
|
||||
self.assertEqual( 653, lineNo )
|
||||
|
||||
def testEnumSymbols( self ):
|
||||
lst = target.module.enumSymbols()
|
||||
|
@ -41,11 +41,10 @@ class TypedVarTest( unittest.TestCase ):
|
||||
target.module.offset("g_structTestPtr") )
|
||||
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_field1", pykd.typeInfo("UInt8B"))
|
||||
tvCustomStruct = pykd.typedVar( customStructTest.ptrTo(),
|
||||
target.module.offset("g_structTestPtr") )
|
||||
tvCustomStruct = pykd.typedVar( customStructTest.ptrTo(), target.module.offset("g_structTestPtr") )
|
||||
self.assertEqual( 500, tvCustomStruct.deref().m_field1 )
|
||||
|
||||
def testConst(self):
|
||||
|
@ -109,7 +109,6 @@ class TypeInfoTest( unittest.TestCase ):
|
||||
|
||||
ti2 = target.module.type( "struct2" )
|
||||
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") )
|
||||
|
||||
def testSize( self ):
|
||||
@ -199,10 +198,14 @@ class TypeInfoTest( unittest.TestCase ):
|
||||
|
||||
def testStaticField(self):
|
||||
ti = pykd.typeInfo( "g_classChild" )
|
||||
self.assertNotEqual( 0, ti.m_staticField.staticOffset() )
|
||||
if not ti.m_staticConst.staticOffset():
|
||||
self.assertNotEqual( 0, ti.staticOffset( "m_staticField" ) )
|
||||
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.assertNotEqual( 0, ti.m_stdstr.staticOffset() )
|
||||
|
||||
def testVfnTable(self):
|
||||
ti = pykd.typeInfo( "g_classChild" )
|
||||
self.assertTrue( hasattr( ti, "__VFN_table" ) )
|
||||
|
||||
def testUdtSubscribe(self):
|
||||
ti = pykd.typeInfo( "g_virtChild" )
|
||||
@ -214,3 +217,8 @@ class TypeInfoTest( unittest.TestCase ):
|
||||
ti = target.module.type("structNullSize")
|
||||
self.assertEqual( 0, len(ti) )
|
||||
|
||||
def testDerefName(self):
|
||||
entry = pykd.typedVar("entry1").Flink
|
||||
self.assertEqual( "_LIST_ENTRY*", entry.type().name() )
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user