[0.1.x] + support constant variables without RVA

git-svn-id: https://pykd.svn.codeplex.com/svn@74822 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\EreTIk_cp 2012-03-09 16:26:11 +00:00 committed by Mikhail I. Izmestev
parent 012b064e1d
commit 6b11102280
18 changed files with 358 additions and 71 deletions

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <map> #include <map>
#include <DbgEng.h>
#include <CvConst.h> #include <CvConst.h>
#include "context.h" #include "context.h"

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <string> #include <string>
#include <dbgeng.h>
#include <dbghelp.h> #include <dbghelp.h>
#include <boost\smart_ptr\scoped_ptr.hpp> #include <boost\smart_ptr\scoped_ptr.hpp>

View File

@ -6,7 +6,6 @@
#include "stdafx.h" #include "stdafx.h"
#include <dbgeng.h>
#include "dbgobj.h" #include "dbgobj.h"
#include "module.h" #include "module.h"
#include "dbgclient.h" #include "dbgclient.h"

View File

@ -1,6 +1,5 @@
#include "stdafx.h" #include "stdafx.h"
#include <dbgeng.h>
#include <dia2.h> #include <dia2.h>
#include <boost/tokenizer.hpp> #include <boost/tokenizer.hpp>

View File

@ -1,7 +1,5 @@
#pragma once #pragma once
#include <dbgeng.h>
namespace pykd { namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <dbgeng.h>
#include "dbgexcept.h" #include "dbgexcept.h"
#include "synsymbol.h" #include "synsymbol.h"

View File

@ -207,7 +207,7 @@ python::object Symbol::getValue()
case VT_I8: case VT_I8:
case VT_UI8: case VT_UI8:
return python::object( float(vtValue.llVal) ); return python::object( vtValue.llVal );
case VT_R4: case VT_R4:
return python::object( double(vtValue.fltVal) ); return python::object( double(vtValue.fltVal) );

View File

@ -4,7 +4,6 @@
#pragma once #pragma once
#include <DbgEng.h>
#include "synsymbol.h" #include "synsymbol.h"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -22,6 +22,7 @@ struct addLocals {
ContextPtr m_ctx; ContextPtr m_ctx;
IDebugClient4 *m_client; IDebugClient4 *m_client;
ULONG m_formalNameCounter; ULONG m_formalNameCounter;
CComPtr< IDebugDataSpaces4 > m_dataSpaces;
void append(pyDia::SymbolPtr symParent); void append(pyDia::SymbolPtr symParent);
@ -139,7 +140,7 @@ TypedVarPtr addLocals::getTypeVarByOffset(
TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symType ); TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symType );
return TypedVar::getTypedVar( m_client, typeInfo, varOffset ); return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, varOffset) );
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -199,7 +200,7 @@ python::dict DebugClient::getLocals(ContextPtr ctx OPTIONAL)
return python::dict(); // out of function debug range return python::dict(); // out of function debug range
python::dict locals; python::dict locals;
impl::addLocals Locals = { locals, mod, rva, ctx, m_client, 0 }; impl::addLocals Locals = { locals, mod, rva, ctx, m_client, 0, m_dataSpaces };
Locals.append(symFunc); Locals.append(symFunc);

View File

@ -192,7 +192,7 @@ Module::reloadSymbols()
TypedVarPtr TypedVarPtr
Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr ) Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
{ {
return TypedVar::getTypedVar( m_client, getTypeByName(typeName), addr ); return TypedVar::getTypedVar( m_client, getTypeByName(typeName), VarDataMemory::factory(m_dataSpaces, addr) );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -200,7 +200,7 @@ Module::getTypedVarByTypeName( const std::string &typeName, ULONG64 addr )
TypedVarPtr TypedVarPtr
Module::getTypedVarByType( const TypeInfoPtr &typeInfo, ULONG64 addr ) Module::getTypedVarByType( const TypeInfoPtr &typeInfo, ULONG64 addr )
{ {
return TypedVar::getTypedVar( m_client, typeInfo, addr ); return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, addr) );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -210,7 +210,7 @@ Module::getTypedVarByName( const std::string &symName )
{ {
HRESULT hres; HRESULT hres;
pyDia::SymbolPtr typeSym = getDia()->getChildByName( symName ); pyDia::SymbolPtr symVar = getDia()->getChildByName( symName );
std::string fullName = m_name; std::string fullName = m_name;
fullName += '!'; fullName += '!';
@ -220,10 +220,16 @@ Module::getTypedVarByName( const std::string &symName )
hres = m_symbols->GetOffsetByName( fullName.c_str(), &offset ); hres = m_symbols->GetOffsetByName( fullName.c_str(), &offset );
if ( FAILED( hres ) ) TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symVar->getType() );
throw DbgException("IDebugSymbols::GetOffsetByName failed" );
return TypedVar::getTypedVar( m_client, TypeInfo::getTypeInfo( typeSym->getType() ), offset ); if ( FAILED( hres ) )
{
if ( LocIsConstant == symVar->getLocType() )
return TypedVar::getTypedVar( m_client, typeInfo, VarDataConst::factory(m_control, symVar) );
throw DbgException("IDebugSymbols::GetOffsetByName failed" );
}
return TypedVar::getTypedVar( m_client, typeInfo, VarDataMemory::factory(m_dataSpaces, offset) );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -301,7 +307,9 @@ TypedVarPtr Module::containingRecordByName( ULONG64 address, const std::string &
TypeInfoPtr fieldTypeInfo = typeInfo->getField( fieldName ); TypeInfoPtr fieldTypeInfo = typeInfo->getField( fieldName );
return TypedVar::getTypedVar( m_client, typeInfo, address - fieldTypeInfo->getOffset() ); VarDataPtr varData = VarDataMemory::factory( m_dataSpaces, address - fieldTypeInfo->getOffset() );
return TypedVar::getTypedVar( m_client, typeInfo, varData );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -312,7 +320,9 @@ TypedVarPtr Module::containingRecordByType( ULONG64 address, const TypeInfoPtr &
TypeInfoPtr fieldTypeInfo = typeInfo->getField( fieldName ); TypeInfoPtr fieldTypeInfo = typeInfo->getField( fieldName );
return TypedVar::getTypedVar( m_client, typeInfo, address - fieldTypeInfo->getOffset() ); VarDataPtr varData = VarDataMemory::factory( m_dataSpaces, address - fieldTypeInfo->getOffset() );
return TypedVar::getTypedVar( m_client, typeInfo, varData );
} }

View File

@ -485,6 +485,10 @@
RelativePath=".\typeinfo.cpp" RelativePath=".\typeinfo.cpp"
> >
</File> </File>
<File
RelativePath=".\vardata.cpp"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
@ -615,6 +619,10 @@
RelativePath=".\utils.h" RelativePath=".\utils.h"
> >
</File> </File>
<File
RelativePath=".\vardata.h"
>
</File>
<File <File
RelativePath=".\windbg.h" RelativePath=".\windbg.h"
> >

View File

@ -33,6 +33,8 @@
#include <dia2.h> #include <dia2.h>
#include <DbgEng.h>
// //
//#ifndef __field_ecount_opt //#ifndef __field_ecount_opt
//#define __field_ecount_opt(x) //#define __field_ecount_opt(x)

View File

@ -5,7 +5,6 @@
#pragma once #pragma once
#include "dbgexcept.h" #include "dbgexcept.h"
#include <DbgEng.h>
#include <map> #include <map>
namespace pykd { namespace pykd {

View File

@ -10,43 +10,43 @@ namespace pykd {
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVarPtr TypedVar::getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) TypedVarPtr TypedVar::getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
{ {
TypedVarPtr tv; TypedVarPtr tv;
if ( typeInfo->isBasicType() ) if ( typeInfo->isBasicType() )
{ {
tv.reset( new BasicTypedVar( client, typeInfo, offset) ); tv.reset( new BasicTypedVar( client, typeInfo, varData) );
return tv; return tv;
} }
if ( typeInfo->isPointer() ) if ( typeInfo->isPointer() )
{ {
tv.reset( new PtrTypedVar( client, typeInfo, offset ) ); tv.reset( new PtrTypedVar( client, typeInfo, varData ) );
return tv; return tv;
} }
if ( typeInfo->isArray() ) if ( typeInfo->isArray() )
{ {
tv.reset( new ArrayTypedVar( client, typeInfo, offset ) ); tv.reset( new ArrayTypedVar( client, typeInfo, varData ) );
return tv; return tv;
} }
if ( typeInfo->isUserDefined() ) if ( typeInfo->isUserDefined() )
{ {
tv.reset( new UdtTypedVar( client, typeInfo, offset ) ); tv.reset( new UdtTypedVar( client, typeInfo, varData ) );
return tv; return tv;
} }
if ( typeInfo->isBitField() ) if ( typeInfo->isBitField() )
{ {
tv.reset( new BitFieldVar( client, typeInfo, offset ) ); tv.reset( new BitFieldVar( client, typeInfo, varData ) );
return tv; return tv;
} }
if ( typeInfo->isEnum() ) if ( typeInfo->isEnum() )
{ {
tv.reset( new EnumTypedVar( client, typeInfo, offset ) ); tv.reset( new EnumTypedVar( client, typeInfo, varData ) );
return tv; return tv;
} }
@ -57,10 +57,10 @@ TypedVarPtr TypedVar::getTypedVar( IDebugClient4 *client, const TypeInfoPtr& t
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData ) :
DbgObject( client ), DbgObject( client ),
m_typeInfo( typeInfo ), m_typeInfo( typeInfo ),
m_offset( offset ), m_varData( varData ),
m_dataKind( DataIsGlobal ) m_dataKind( DataIsGlobal )
{ {
m_size = m_typeInfo->getSize(); m_size = m_typeInfo->getSize();
@ -70,8 +70,7 @@ TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64
BaseTypeVariant BasicTypedVar::getValue() BaseTypeVariant BasicTypedVar::getValue()
{ {
ULONG64 val = 0; ULONG64 val = 0;
m_varData->read(&val, getSize());
readMemory( m_dataSpaces, m_offset, &val, getSize(), false );
if ( m_typeInfo->getName() == "Char" ) if ( m_typeInfo->getName() == "Char" )
return (LONG)*(PCHAR)&val; return (LONG)*(PCHAR)&val;
@ -121,7 +120,7 @@ std::string BasicTypedVar::print()
{ {
std::stringstream sstr; std::stringstream sstr;
sstr << m_typeInfo->getName() << " at " << std::hex << m_offset; sstr << m_typeInfo->getName() << " " << m_varData->asString();
sstr << " Value: " << printValue(); sstr << " Value: " << printValue();
return sstr.str(); return sstr.str();
@ -143,22 +142,15 @@ std::string BasicTypedVar::printValue()
BaseTypeVariant PtrTypedVar::getValue() BaseTypeVariant PtrTypedVar::getValue()
{ {
ULONG64 val = 0; return m_varData->readPtr();
readMemoryPtr( m_dataSpaces, m_offset, &val );
return val;
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
TypedVarPtr PtrTypedVar::deref() TypedVarPtr PtrTypedVar::deref()
{ {
ULONG64 val = 0; VarDataPtr varData = VarDataMemory::factory( m_dataSpaces, m_varData->readPtr() );
return TypedVar::getTypedVar( m_client, m_typeInfo->deref(), varData );
readMemoryPtr( m_dataSpaces, m_offset, &val );
return TypedVar::getTypedVar( m_client, m_typeInfo->deref(), val );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -167,7 +159,7 @@ std::string PtrTypedVar::print()
{ {
std::stringstream sstr; std::stringstream sstr;
sstr << m_typeInfo->getName() << " at 0x" << std::hex << m_offset; sstr << m_typeInfo->getName() << " " << m_varData->asString();
sstr << " Value: " << printValue(); sstr << " Value: " << printValue();
return sstr.str(); return sstr.str();
@ -190,7 +182,7 @@ std::string ArrayTypedVar::print()
{ {
std::stringstream sstr; std::stringstream sstr;
sstr << m_typeInfo->getName() << " at 0x" << std::hex << m_offset; sstr << m_typeInfo->getName() << " " << m_varData->asString();
return sstr.str(); return sstr.str();
} }
@ -211,7 +203,7 @@ TypedVarPtr ArrayTypedVar::getElementByIndex( ULONG index )
TypeInfoPtr elementType = m_typeInfo->getElementType(); TypeInfoPtr elementType = m_typeInfo->getElementType();
return TypedVar::getTypedVar( m_client, elementType, m_offset + elementType->getSize()*index ); return TypedVar::getTypedVar( m_client, elementType, m_varData->fork(elementType->getSize()*index) );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -221,7 +213,7 @@ UdtTypedVar::getField( const std::string &fieldName )
{ {
TypeInfoPtr fieldType = m_typeInfo->getField( fieldName ); TypeInfoPtr fieldType = m_typeInfo->getField( fieldName );
return TypedVar::getTypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ); return TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldType->getOffset()) );
} }
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
@ -230,12 +222,12 @@ std::string UdtTypedVar::print()
{ {
std::stringstream sstr; std::stringstream sstr;
sstr << "struct/class: " << m_typeInfo->getName() << " at 0x" << std::hex << m_offset << std::endl; sstr << "struct/class: " << m_typeInfo->getName() << " " << m_varData->asString();
for ( ULONG i = 0; i < m_typeInfo->getFieldCount(); ++i ) for ( ULONG i = 0; i < m_typeInfo->getFieldCount(); ++i )
{ {
TypeInfoPtr fieldType = m_typeInfo->getFieldByIndex(i); TypeInfoPtr fieldType = m_typeInfo->getFieldByIndex(i);
TypedVarPtr fieldVar = TypedVar::getTypedVar( m_client, fieldType, m_offset + fieldType->getOffset() ); TypedVarPtr fieldVar = TypedVar::getTypedVar( m_client, fieldType, m_varData->fork(fieldType->getOffset()) );
sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldType->getOffset(); sstr << " +" << std::right << std::setw(4) << std::setfill('0') << std::hex << fieldType->getOffset();
sstr << " " << std::left << std::setw( 20 ) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':'; sstr << " " << std::left << std::setw( 20 ) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':';
@ -261,7 +253,7 @@ BaseTypeVariant BitFieldVar::getValue()
{ {
ULONG64 val = 0; ULONG64 val = 0;
readMemory( m_dataSpaces, m_offset, &val, getSize(), false ); m_varData->read( &val, getSize() );
val >>= m_typeInfo->getBitOffset(); val >>= m_typeInfo->getBitOffset();
val &= m_typeInfo->getBitWidth(); val &= m_typeInfo->getBitWidth();
@ -303,7 +295,7 @@ BaseTypeVariant EnumTypedVar::getValue()
{ {
ULONG val = 0; ULONG val = 0;
readMemory( m_dataSpaces, m_offset, &val, getSize(), false ); m_varData->read( &val, getSize() );
return val; return val;
}; };
@ -314,7 +306,7 @@ std::string EnumTypedVar::print()
{ {
std::stringstream sstr; std::stringstream sstr;
sstr << "enum: " << m_typeInfo->getName() << " at 0x" << std::hex << m_offset; sstr << "enum: " << m_typeInfo->getName() << " " << m_varData->asString();
sstr << " Value: " << printValue(); sstr << " Value: " << printValue();
return sstr.str(); return sstr.str();

View File

@ -4,6 +4,7 @@
#include "intbase.h" #include "intbase.h"
#include "dbgobj.h" #include "dbgobj.h"
#include "dbgexcept.h" #include "dbgexcept.h"
#include "vardata.h"
namespace pykd { namespace pykd {
@ -18,10 +19,10 @@ class TypedVar : public intBase, protected DbgObject {
public: public:
static TypedVarPtr getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ); static TypedVarPtr getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData );
ULONG64 getAddress() const { ULONG64 getAddress() const {
return m_offset; return m_varData->getAddr();
} }
ULONG getSize() const { ULONG getSize() const {
@ -66,7 +67,7 @@ public:
} }
virtual BaseTypeVariant getValue() { virtual BaseTypeVariant getValue() {
return m_offset; return m_varData->getAddr();
} }
ULONG getDataKind() const { ULONG getDataKind() const {
@ -79,11 +80,11 @@ public:
protected: protected:
TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ); TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData );
TypeInfoPtr m_typeInfo; TypeInfoPtr m_typeInfo;
ULONG64 m_offset; VarDataPtr m_varData;
ULONG m_size; ULONG m_size;
@ -97,7 +98,10 @@ class BasicTypedVar : public TypedVar {
public: public:
BasicTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} BasicTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
: TypedVar(client, typeInfo, varData)
{
}
virtual std::string print(); virtual std::string print();
@ -114,7 +118,10 @@ class PtrTypedVar : public TypedVar {
public: public:
PtrTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} PtrTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
: TypedVar(client, typeInfo, varData)
{
}
virtual std::string print(); virtual std::string print();
@ -132,7 +139,10 @@ class ArrayTypedVar: public TypedVar {
public: public:
ArrayTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} ArrayTypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
: TypedVar(client, typeInfo, varData)
{
}
virtual ULONG getElementCount() { virtual ULONG getElementCount() {
return m_typeInfo->getCount(); return m_typeInfo->getCount();
@ -151,7 +161,10 @@ class UdtTypedVar : public TypedVar {
public: public:
UdtTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} UdtTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
: TypedVar(client, typeInfo, varData)
{
}
virtual std::string print(); virtual std::string print();
@ -166,7 +179,10 @@ class BitFieldVar: public TypedVar {
public: public:
BitFieldVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} BitFieldVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
: TypedVar(client, typeInfo, varData)
{
}
virtual std::string printValue(); virtual std::string printValue();
@ -178,7 +194,10 @@ public:
class EnumTypedVar : public TypedVar { class EnumTypedVar : public TypedVar {
public: public:
EnumTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset ) : TypedVar(client, typeInfo, offset){} EnumTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData )
: TypedVar(client, typeInfo, varData)
{
}
virtual std::string print(); virtual std::string print();

171
pykd/vardata.cpp Normal file
View File

@ -0,0 +1,171 @@
//
// Access to variable data
//
#include "stdafx.h"
#include "vardata.h"
#include "dbgmem.h"
#include "dbgexcept.h"
////////////////////////////////////////////////////////////////////////////////
namespace pykd {
////////////////////////////////////////////////////////////////////////////////
VarDataMemory::VarDataMemory(CComPtr< IDebugDataSpaces4 > dataSpaces, ULONG64 addr)
: m_dataSpaces(dataSpaces)
, m_addr(addr)
{
}
////////////////////////////////////////////////////////////////////////////////
std::string VarDataMemory::asString() const
{
std::stringstream sstr;
sstr << "at 0x" << std::hex << m_addr;
return sstr.str();
}
////////////////////////////////////////////////////////////////////////////////
ULONG64 VarDataMemory::getAddr() const
{
return m_addr;
}
////////////////////////////////////////////////////////////////////////////////
VarDataPtr VarDataMemory::fork(ULONG offset) const
{
return VarDataPtr( new VarDataMemory(m_dataSpaces, m_addr + offset) );
}
////////////////////////////////////////////////////////////////////////////////
void VarDataMemory::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const
{
readMemory(m_dataSpaces, m_addr + offset, buffer, length);
}
////////////////////////////////////////////////////////////////////////////////
ULONG64 VarDataMemory::readPtr() const
{
ULONG64 ptrValue = 0;
readMemoryPtr(m_dataSpaces, m_addr, &ptrValue);
return ptrValue;
}
////////////////////////////////////////////////////////////////////////////////
VarDataConst::VarDataConst(CComPtr< IDebugControl4 > control, pyDia::SymbolPtr symData)
: m_control(control)
, m_fieldOffset(0)
, m_dataBuff( new std::vector< UCHAR >((size_t)symData->getType()->getSize(), 0) )
{
VARIANT vtValue = {0};
symData->getValue(vtValue);
switch (vtValue.vt)
{
case VT_I1:
case VT_UI1:
fillDataBuff(vtValue.bVal);
break;
case VT_BOOL:
fillDataBuff(!!vtValue.iVal);
break;
case VT_I2:
case VT_UI2:
fillDataBuff(vtValue.iVal);
break;
case VT_I4:
case VT_UI4:
case VT_INT:
case VT_UINT:
case VT_ERROR:
case VT_HRESULT:
fillDataBuff(vtValue.lVal);
break;
case VT_I8:
case VT_UI8:
fillDataBuff(vtValue.llVal);
break;
case VT_R4:
fillDataBuff(vtValue.fltVal);
break;
case VT_R8:
fillDataBuff(vtValue.dblVal);
break;
default:
throw DbgException( "Unsupported const value" );
}
}
////////////////////////////////////////////////////////////////////////////////
std::string VarDataConst::asString() const
{
return "<constant>";
}
////////////////////////////////////////////////////////////////////////////////
ULONG64 VarDataConst::getAddr() const
{
throw DbgException("Constant does not have address");
}
////////////////////////////////////////////////////////////////////////////////
VarDataPtr VarDataConst::fork(ULONG offset) const
{
return VarDataPtr(new VarDataConst(*this, offset));
}
////////////////////////////////////////////////////////////////////////////////
void VarDataConst::read(PVOID buffer, ULONG length, ULONG offset /*= 0*/) const
{
if (offset + length > m_dataBuff->size())
throw DbgException("Internal error in " __FUNCTION__);
RtlCopyMemory(buffer, &m_dataBuff->at(offset), length);
}
////////////////////////////////////////////////////////////////////////////////'
ULONG64 VarDataConst::readPtr() const
{
ULONG64 val = 0;
const ULONG length = (S_OK == m_control->IsPointer64Bit()) ? 8 : 4;
if (length > m_dataBuff->size())
throw DbgException("Internal error in " __FUNCTION__);
RtlCopyMemory(&val, &m_dataBuff->at(0), length);
return val;
}
////////////////////////////////////////////////////////////////////////////////
VarDataConst::VarDataConst(const VarDataConst &from, ULONG fieldOffset)
: m_control(from.m_control)
, m_fieldOffset(from.m_fieldOffset + fieldOffset)
, m_dataBuff(from.m_dataBuff)
{
}
////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////

95
pykd/vardata.h Normal file
View File

@ -0,0 +1,95 @@
//
// Access to variable data
//
#pragma once
////////////////////////////////////////////////////////////////////////////////
#include <array>
#include <boost\smart_ptr\shared_ptr.hpp>
#include "diawrapper.h"
////////////////////////////////////////////////////////////////////////////////
namespace pykd {
// pointer to variable data access interface
interface IVarData;
typedef boost::shared_ptr< IVarData > VarDataPtr;
// access to variable data interface
interface IVarData
{
virtual ~IVarData() {}
virtual std::string asString() const = 0;
virtual ULONG64 getAddr() const = 0;
virtual VarDataPtr fork(ULONG offset) const = 0;
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const = 0;
virtual ULONG64 readPtr() const = 0;
};
// variable in memory
class VarDataMemory : public IVarData
{
public:
// IVarData implementation
virtual std::string asString() const override;
virtual ULONG64 getAddr() const override;
virtual VarDataPtr fork(ULONG offset) const override;
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const override;
virtual ULONG64 readPtr() const override;
static VarDataPtr factory(CComPtr< IDebugDataSpaces4 > dataSpaces, ULONG64 addr) {
return VarDataPtr( new VarDataMemory(dataSpaces, addr) );
}
protected:
VarDataMemory(CComPtr< IDebugDataSpaces4 > dataSpaces, ULONG64 addr);
private:
CComPtr< IDebugDataSpaces4 > m_dataSpaces;
ULONG64 m_addr;
};
// constant variable
class VarDataConst : public IVarData
{
public:
// IVarData implementation
virtual std::string asString() const override;
virtual ULONG64 getAddr() const override;
virtual VarDataPtr fork(ULONG offset) const override;
virtual void read(PVOID buffer, ULONG length, ULONG offset = 0) const override;
virtual ULONG64 readPtr() const override;
static VarDataPtr factory(CComPtr< IDebugControl4 > control, pyDia::SymbolPtr symData) {
return VarDataPtr( new VarDataConst(control, symData) );
}
protected:
VarDataConst(CComPtr< IDebugControl4 > control, pyDia::SymbolPtr symData);
VarDataConst(const VarDataConst &from, ULONG fieldOffset);
template<typename T>
void fillDataBuff(const T &data)
{
RtlCopyMemory( &m_dataBuff->at(0), &data, min(sizeof(T), m_dataBuff->size()) );
}
private:
CComPtr< IDebugControl4 > m_control;
ULONG m_fieldOffset;
boost::shared_ptr< std::vector<UCHAR> > m_dataBuff;
};
}
//////////////////////////////////////////////////////////////////////////

View File

@ -23,10 +23,8 @@ class TypedVarTest( unittest.TestCase ):
self.assertEqual( -8, target.module.typedVar( "g_longlongValue" ) ) self.assertEqual( -8, target.module.typedVar( "g_longlongValue" ) )
def testConst(self): def testConst(self):
try: self.assertEqual( True, target.module.typedVar( "g_constBoolValue" ) )
self.assertEqual( True, target.module.typedVar( "g_constBoolValue" ) ) self.assertEqual( 0x5555, target.module.typedVar( "g_constNumValue" ) )
except pykd.BaseException:
self.assertFalse( "FIXME: constants without RVA is not supported" )
def testGetAddress( self ): def testGetAddress( self ):
tv = target.module.typedVar( "structTest", target.module.g_structTest ) tv = target.module.typedVar( "structTest", target.module.g_structTest )