mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04: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
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <DbgEng.h>
|
|
||||||
#include <CvConst.h>
|
#include <CvConst.h>
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
@ -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>
|
||||||
|
@ -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"
|
||||||
|
@ -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>
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <dbgeng.h>
|
|
||||||
|
|
||||||
namespace pykd {
|
namespace pykd {
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <dbgeng.h>
|
|
||||||
#include "dbgexcept.h"
|
#include "dbgexcept.h"
|
||||||
#include "synsymbol.h"
|
#include "synsymbol.h"
|
||||||
|
|
||||||
@ -49,8 +48,8 @@ protected:
|
|||||||
|
|
||||||
virtual ~DbgObject() {};
|
virtual ~DbgObject() {};
|
||||||
|
|
||||||
CComPtr<IDebugClient5> m_client5;
|
CComPtr<IDebugClient5> m_client5;
|
||||||
CComPtr<IDebugClient4> m_client;
|
CComPtr<IDebugClient4> m_client;
|
||||||
CComPtr<IDebugControl4> m_control;
|
CComPtr<IDebugControl4> m_control;
|
||||||
CComPtr<IDebugSymbols3> m_symbols;
|
CComPtr<IDebugSymbols3> m_symbols;
|
||||||
CComPtr<IDebugAdvanced2> m_advanced;
|
CComPtr<IDebugAdvanced2> m_advanced;
|
||||||
|
@ -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) );
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <DbgEng.h>
|
|
||||||
#include "synsymbol.h"
|
#include "synsymbol.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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"
|
||||||
>
|
>
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
@ -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();
|
||||||
@ -69,9 +69,8 @@ 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();
|
||||||
@ -179,7 +171,7 @@ std::string PtrTypedVar::printValue()
|
|||||||
{
|
{
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
|
|
||||||
sstr << "0x" << boost::apply_visitor( VariantToHex(), getValue() );
|
sstr << "0x" << boost::apply_visitor( VariantToHex(), getValue() );
|
||||||
|
|
||||||
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();
|
||||||
|
@ -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
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" ) )
|
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 )
|
||||||
|
Loading…
Reference in New Issue
Block a user