mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-22 05:13:22 +08:00
[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:
parent
012b064e1d
commit
6b11102280
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <DbgEng.h>
|
||||
#include <CvConst.h>
|
||||
|
||||
#include "context.h"
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <dbgeng.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include <boost\smart_ptr\scoped_ptr.hpp>
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <dbgeng.h>
|
||||
#include "dbgobj.h"
|
||||
#include "module.h"
|
||||
#include "dbgclient.h"
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <dbgeng.h>
|
||||
#include <dia2.h>
|
||||
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <dbgeng.h>
|
||||
|
||||
namespace pykd {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <dbgeng.h>
|
||||
#include "dbgexcept.h"
|
||||
#include "synsymbol.h"
|
||||
|
||||
|
@ -207,7 +207,7 @@ python::object Symbol::getValue()
|
||||
|
||||
case VT_I8:
|
||||
case VT_UI8:
|
||||
return python::object( float(vtValue.llVal) );
|
||||
return python::object( vtValue.llVal );
|
||||
|
||||
case VT_R4:
|
||||
return python::object( double(vtValue.fltVal) );
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <DbgEng.h>
|
||||
#include "synsymbol.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -22,6 +22,7 @@ struct addLocals {
|
||||
ContextPtr m_ctx;
|
||||
IDebugClient4 *m_client;
|
||||
ULONG m_formalNameCounter;
|
||||
CComPtr< IDebugDataSpaces4 > m_dataSpaces;
|
||||
|
||||
void append(pyDia::SymbolPtr symParent);
|
||||
|
||||
@ -139,7 +140,7 @@ TypedVarPtr addLocals::getTypeVarByOffset(
|
||||
|
||||
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
|
||||
|
||||
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);
|
||||
|
||||
|
@ -192,7 +192,7 @@ Module::reloadSymbols()
|
||||
TypedVarPtr
|
||||
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
|
||||
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;
|
||||
|
||||
pyDia::SymbolPtr typeSym = getDia()->getChildByName( symName );
|
||||
pyDia::SymbolPtr symVar = getDia()->getChildByName( symName );
|
||||
|
||||
std::string fullName = m_name;
|
||||
fullName += '!';
|
||||
@ -220,10 +220,16 @@ Module::getTypedVarByName( const std::string &symName )
|
||||
|
||||
hres = m_symbols->GetOffsetByName( fullName.c_str(), &offset );
|
||||
|
||||
if ( FAILED( hres ) )
|
||||
throw DbgException("IDebugSymbols::GetOffsetByName failed" );
|
||||
TypeInfoPtr typeInfo = TypeInfo::getTypeInfo( symVar->getType() );
|
||||
|
||||
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 );
|
||||
|
||||
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 );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -485,6 +485,10 @@
|
||||
RelativePath=".\typeinfo.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\vardata.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
@ -615,6 +619,10 @@
|
||||
RelativePath=".\utils.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\vardata.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\windbg.h"
|
||||
>
|
||||
|
@ -33,6 +33,8 @@
|
||||
|
||||
#include <dia2.h>
|
||||
|
||||
#include <DbgEng.h>
|
||||
|
||||
//
|
||||
//#ifndef __field_ecount_opt
|
||||
//#define __field_ecount_opt(x)
|
||||
|
@ -5,7 +5,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "dbgexcept.h"
|
||||
#include <DbgEng.h>
|
||||
#include <map>
|
||||
|
||||
namespace pykd {
|
||||
|
@ -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;
|
||||
|
||||
if ( typeInfo->isBasicType() )
|
||||
{
|
||||
tv.reset( new BasicTypedVar( client, typeInfo, offset) );
|
||||
tv.reset( new BasicTypedVar( client, typeInfo, varData) );
|
||||
return tv;
|
||||
}
|
||||
|
||||
if ( typeInfo->isPointer() )
|
||||
{
|
||||
tv.reset( new PtrTypedVar( client, typeInfo, offset ) );
|
||||
tv.reset( new PtrTypedVar( client, typeInfo, varData ) );
|
||||
return tv;
|
||||
}
|
||||
|
||||
if ( typeInfo->isArray() )
|
||||
{
|
||||
tv.reset( new ArrayTypedVar( client, typeInfo, offset ) );
|
||||
tv.reset( new ArrayTypedVar( client, typeInfo, varData ) );
|
||||
return tv;
|
||||
}
|
||||
|
||||
if ( typeInfo->isUserDefined() )
|
||||
{
|
||||
tv.reset( new UdtTypedVar( client, typeInfo, offset ) );
|
||||
tv.reset( new UdtTypedVar( client, typeInfo, varData ) );
|
||||
return tv;
|
||||
}
|
||||
|
||||
if ( typeInfo->isBitField() )
|
||||
{
|
||||
tv.reset( new BitFieldVar( client, typeInfo, offset ) );
|
||||
tv.reset( new BitFieldVar( client, typeInfo, varData ) );
|
||||
return tv;
|
||||
}
|
||||
|
||||
if ( typeInfo->isEnum() )
|
||||
{
|
||||
tv.reset( new EnumTypedVar( client, typeInfo, offset ) );
|
||||
tv.reset( new EnumTypedVar( client, typeInfo, varData ) );
|
||||
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 ),
|
||||
m_typeInfo( typeInfo ),
|
||||
m_offset( offset ),
|
||||
m_varData( varData ),
|
||||
m_dataKind( DataIsGlobal )
|
||||
{
|
||||
m_size = m_typeInfo->getSize();
|
||||
@ -70,8 +70,7 @@ TypedVar::TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64
|
||||
BaseTypeVariant BasicTypedVar::getValue()
|
||||
{
|
||||
ULONG64 val = 0;
|
||||
|
||||
readMemory( m_dataSpaces, m_offset, &val, getSize(), false );
|
||||
m_varData->read(&val, getSize());
|
||||
|
||||
if ( m_typeInfo->getName() == "Char" )
|
||||
return (LONG)*(PCHAR)&val;
|
||||
@ -121,7 +120,7 @@ std::string BasicTypedVar::print()
|
||||
{
|
||||
std::stringstream sstr;
|
||||
|
||||
sstr << m_typeInfo->getName() << " at " << std::hex << m_offset;
|
||||
sstr << m_typeInfo->getName() << " " << m_varData->asString();
|
||||
sstr << " Value: " << printValue();
|
||||
|
||||
return sstr.str();
|
||||
@ -143,22 +142,15 @@ std::string BasicTypedVar::printValue()
|
||||
|
||||
BaseTypeVariant PtrTypedVar::getValue()
|
||||
{
|
||||
ULONG64 val = 0;
|
||||
|
||||
readMemoryPtr( m_dataSpaces, m_offset, &val );
|
||||
|
||||
return val;
|
||||
return m_varData->readPtr();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypedVarPtr PtrTypedVar::deref()
|
||||
{
|
||||
ULONG64 val = 0;
|
||||
|
||||
readMemoryPtr( m_dataSpaces, m_offset, &val );
|
||||
|
||||
return TypedVar::getTypedVar( m_client, m_typeInfo->deref(), val );
|
||||
VarDataPtr varData = VarDataMemory::factory( m_dataSpaces, m_varData->readPtr() );
|
||||
return TypedVar::getTypedVar( m_client, m_typeInfo->deref(), varData );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
@ -167,7 +159,7 @@ std::string PtrTypedVar::print()
|
||||
{
|
||||
std::stringstream sstr;
|
||||
|
||||
sstr << m_typeInfo->getName() << " at 0x" << std::hex << m_offset;
|
||||
sstr << m_typeInfo->getName() << " " << m_varData->asString();
|
||||
sstr << " Value: " << printValue();
|
||||
|
||||
return sstr.str();
|
||||
@ -190,7 +182,7 @@ std::string ArrayTypedVar::print()
|
||||
{
|
||||
std::stringstream sstr;
|
||||
|
||||
sstr << m_typeInfo->getName() << " at 0x" << std::hex << m_offset;
|
||||
sstr << m_typeInfo->getName() << " " << m_varData->asString();
|
||||
|
||||
return sstr.str();
|
||||
}
|
||||
@ -211,7 +203,7 @@ TypedVarPtr ArrayTypedVar::getElementByIndex( ULONG index )
|
||||
|
||||
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 );
|
||||
|
||||
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;
|
||||
|
||||
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 )
|
||||
{
|
||||
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::left << std::setw( 20 ) << std::setfill(' ') << m_typeInfo->getFieldNameByIndex(i) << ':';
|
||||
@ -261,7 +253,7 @@ BaseTypeVariant BitFieldVar::getValue()
|
||||
{
|
||||
ULONG64 val = 0;
|
||||
|
||||
readMemory( m_dataSpaces, m_offset, &val, getSize(), false );
|
||||
m_varData->read( &val, getSize() );
|
||||
|
||||
val >>= m_typeInfo->getBitOffset();
|
||||
val &= m_typeInfo->getBitWidth();
|
||||
@ -303,7 +295,7 @@ BaseTypeVariant EnumTypedVar::getValue()
|
||||
{
|
||||
ULONG val = 0;
|
||||
|
||||
readMemory( m_dataSpaces, m_offset, &val, getSize(), false );
|
||||
m_varData->read( &val, getSize() );
|
||||
|
||||
return val;
|
||||
};
|
||||
@ -314,7 +306,7 @@ std::string EnumTypedVar::print()
|
||||
{
|
||||
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();
|
||||
|
||||
return sstr.str();
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "intbase.h"
|
||||
#include "dbgobj.h"
|
||||
#include "dbgexcept.h"
|
||||
#include "vardata.h"
|
||||
|
||||
namespace pykd {
|
||||
|
||||
@ -18,10 +19,10 @@ class TypedVar : public intBase, protected DbgObject {
|
||||
|
||||
public:
|
||||
|
||||
static TypedVarPtr getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset );
|
||||
static TypedVarPtr getTypedVar( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData );
|
||||
|
||||
ULONG64 getAddress() const {
|
||||
return m_offset;
|
||||
return m_varData->getAddr();
|
||||
}
|
||||
|
||||
ULONG getSize() const {
|
||||
@ -66,7 +67,7 @@ public:
|
||||
}
|
||||
|
||||
virtual BaseTypeVariant getValue() {
|
||||
return m_offset;
|
||||
return m_varData->getAddr();
|
||||
}
|
||||
|
||||
ULONG getDataKind() const {
|
||||
@ -79,11 +80,11 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, ULONG64 offset );
|
||||
TypedVar ( IDebugClient4 *client, const TypeInfoPtr& typeInfo, VarDataPtr varData );
|
||||
|
||||
TypeInfoPtr m_typeInfo;
|
||||
|
||||
ULONG64 m_offset;
|
||||
VarDataPtr m_varData;
|
||||
|
||||
ULONG m_size;
|
||||
|
||||
@ -97,7 +98,10 @@ class BasicTypedVar : public TypedVar {
|
||||
|
||||
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();
|
||||
@ -114,7 +118,10 @@ class PtrTypedVar : public TypedVar {
|
||||
|
||||
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();
|
||||
|
||||
@ -132,7 +139,10 @@ class ArrayTypedVar: public TypedVar {
|
||||
|
||||
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() {
|
||||
return m_typeInfo->getCount();
|
||||
@ -151,7 +161,10 @@ class UdtTypedVar : public TypedVar {
|
||||
|
||||
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();
|
||||
|
||||
@ -166,7 +179,10 @@ class BitFieldVar: public TypedVar {
|
||||
|
||||
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();
|
||||
|
||||
@ -178,7 +194,10 @@ public:
|
||||
class EnumTypedVar : public TypedVar {
|
||||
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();
|
||||
|
||||
|
171
pykd/vardata.cpp
Normal file
171
pykd/vardata.cpp
Normal 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
95
pykd/vardata.h
Normal 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
@ -23,10 +23,8 @@ class TypedVarTest( unittest.TestCase ):
|
||||
self.assertEqual( -8, target.module.typedVar( "g_longlongValue" ) )
|
||||
|
||||
def testConst(self):
|
||||
try:
|
||||
self.assertEqual( True, target.module.typedVar( "g_constBoolValue" ) )
|
||||
except pykd.BaseException:
|
||||
self.assertFalse( "FIXME: constants without RVA is not supported" )
|
||||
self.assertEqual( 0x5555, target.module.typedVar( "g_constNumValue" ) )
|
||||
|
||||
def testGetAddress( self ):
|
||||
tv = target.module.typedVar( "structTest", target.module.g_structTest )
|
||||
|
Loading…
Reference in New Issue
Block a user