mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 12:53: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 "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()) );
|
||||||
|
//}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
|
|
||||||
protected:
|
CustomStruct( const std::string &name, ULONG ptrSize, ULONG align ) :
|
||||||
CustomUnion(const std::string &name, ULONG pointerSize)
|
CustomBase( name, ptrSize, align )
|
||||||
: 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
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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" )
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
@ -176,7 +179,8 @@ protected:
|
|||||||
|
|
||||||
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 );
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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::right << std::setw(10) << std::setfill('0') << std::hex << udtField->getStaticOffset();
|
||||||
sstr << " " << std::left << std::setw(18) << std::setfill(' ') << udtField.m_name << ':';
|
sstr << " " << std::left << std::setw(18) << std::setfill(' ') << udtField->getName() << ':';
|
||||||
}
|
|
||||||
else
|
|
||||||
if ( fieldType->isVirtualMember() )
|
|
||||||
{
|
|
||||||
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 << ':';
|
|
||||||
}
|
}
|
||||||
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 );
|
|
||||||
|
|
||||||
}
|
m_fields.push_back( UdtFieldPtr( fieldPtr ) );
|
||||||
|
|
||||||
UdtFieldColl::push_back(
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
213
pykd/typeinfo.h
213
pykd/typeinfo.h
@ -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,
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
254
pykd/udtutils.h
254
pykd/udtutils.h
@ -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
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
@ -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") )
|
|
||||||
|
|
||||||
myType = pykd.createStruct("MyCustomStruct")
|
mySubStruct =tb.createStruct("MySubCustomStruct")
|
||||||
myType.append( "m_uint1", pykd.typeInfo("UInt1B") )
|
mySubStruct.append( "m_uint1", tb.UInt1B )
|
||||||
myType.append( "m_uint4", pykd.typeInfo("UInt4B") )
|
mySubStruct.append( "m_uint2", tb.UInt2B )
|
||||||
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_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)
|
||||||
|
@ -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()
|
||||||
|
@ -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):
|
||||||
|
@ -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() )
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user