[0.1.x] added : cpuReg class

[0.1.x] refactored : context.cpp/h

git-svn-id: https://pykd.svn.codeplex.com/svn@73463 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-01-23 07:50:36 +00:00 committed by Mikhail I. Izmestev
parent 1f7f55917c
commit 0768ce3fe3
9 changed files with 311 additions and 256 deletions

View File

@ -7,9 +7,9 @@
/////////////////////////////////////////////////////////////////////////////////
namespace Ctx {
namespace pykd {
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
namespace I386 {
#include "defctxi386.h"
@ -17,15 +17,13 @@ namespace I386 {
/////////////////////////////////////////////////////////////////////////////////
void Registers::getI386Context(
IDebugAdvanced2 *advanced
)
void ThreadContext::getI386Context()
{
I386::CONTEXT Context = {0};
HRESULT hres = advanced->GetThreadContext(&Context, sizeof(Context));
HRESULT hres = m_advanced->GetThreadContext(&Context, sizeof(Context));
if (S_OK != hres)
throw Exception( "IDebugAdvanced2::GetThreadContext", hres );
throw DbgException( "IDebugAdvanced2::GetThreadContext", hres );
m_regValues[CV_REG_DR0] = Context.Dr0;
m_regValues[CV_REG_DR1] = Context.Dr1;
@ -65,15 +63,13 @@ namespace AMD64 {
/////////////////////////////////////////////////////////////////////////////////
void Registers::getAmd64Context(
IDebugAdvanced2 *advanced
)
void ThreadContext::getAmd64Context()
{
AMD64::CONTEXT Context = {0};
HRESULT hres = advanced->GetThreadContext(&Context, sizeof(Context));
HRESULT hres = m_advanced->GetThreadContext(&Context, sizeof(Context));
if (S_OK != hres)
throw Exception( "IDebugAdvanced2::GetThreadContext", hres);
throw DbgException( "IDebugAdvanced2::GetThreadContext", hres);
m_regValues[CV_AMD64_MXCSR] = Context.MxCsr;
@ -115,66 +111,48 @@ void Registers::getAmd64Context(
/////////////////////////////////////////////////////////////////////////////////
Registers::Registers(
IDebugControl4 *control,
IDebugAdvanced2 *advanced
)
ThreadContext::ThreadContext( IDebugClient4 *client ) :
pykd::DbgObject( client )
{
HRESULT hres = control->GetExecutingProcessorType(&m_processorType);
HRESULT hres = m_control->GetExecutingProcessorType(&m_processorType);
if (S_OK != hres)
throw Exception( "IDebugControl::GetExecutingProcessorType", hres );
throw DbgException( "IDebugControl::GetExecutingProcessorType", hres );
switch (m_processorType)
{
case IMAGE_FILE_MACHINE_I386:
getI386Context(advanced);
getI386Context();
return;
case IMAGE_FILE_MACHINE_AMD64:
getAmd64Context(advanced);
getAmd64Context();
return;
}
std::stringstream sstream;
sstream << __FUNCTION__ << ":\n";
sstream << "Unsupported processor type: 0x" << std::hex << m_processorType;
throw Exception( sstream.str() );
throw DbgException( sstream.str() );
}
/////////////////////////////////////////////////////////////////////////////////
ULONG64 Registers::getValue(ULONG cvRegId) const
{
try
{
return getSubValue(cvRegId);
}
catch (const IsNotSubRegister &)
ULONG64 ThreadContext::getValue(ULONG cvRegId) const
{
ULONG64 val;
if ( getValueNoThrow( cvRegId, val ) )
return val;
throw DbgException(__FUNCTION__ ": Register missing");
}
RegValues::const_iterator it = m_regValues.find(cvRegId);
if (it == m_regValues.end())
throw Exception(__FUNCTION__ ": Register missing");
return it->second;
}
///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
bool Registers::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const
bool ThreadContext::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const
{
try
{
val = getSubValue(cvRegId);
if ( getSubValue(cvRegId, val ) )
return true;
}
catch (const IsNotSubRegister &)
{
}
catch (const Exception &)
{
return false;
}
RegValues::const_iterator it = m_regValues.find(cvRegId);
if (it == m_regValues.end())
@ -184,9 +162,9 @@ bool Registers::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const
return true;
}
/////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
ULONG64 Registers::getIp() const
ULONG64 ThreadContext::getIp() const
{
return getValue(
IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_EIP : CV_AMD64_RIP
@ -195,7 +173,7 @@ ULONG64 Registers::getIp() const
/////////////////////////////////////////////////////////////////////////////////
ULONG64 Registers::getRetReg() const
ULONG64 ThreadContext::getRetReg() const
{
return getValue(
IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_EAX : CV_AMD64_RAX
@ -204,7 +182,7 @@ ULONG64 Registers::getRetReg() const
/////////////////////////////////////////////////////////////////////////////////
ULONG64 Registers::getSp() const
ULONG64 ThreadContext::getSp() const
{
return getValue(
IMAGE_FILE_MACHINE_I386 == m_processorType ? CV_REG_ESP : CV_AMD64_RSP
@ -213,7 +191,7 @@ ULONG64 Registers::getSp() const
/////////////////////////////////////////////////////////////////////////////////
python::object Registers::getByIndex(ULONG ind) const
python::object ThreadContext::getByIndex(ULONG ind) const
{
RegValues::const_iterator it = m_regValues.begin();
for (ULONG i = 0; it != m_regValues.end(); ++i, ++it )
@ -222,10 +200,7 @@ python::object Registers::getByIndex(ULONG ind) const
return python::make_tuple(it->first, it->second);
}
PyErr_SetString(PyExc_IndexError, "Index out of range");
python::throw_error_already_set();
return python::object();
throw PyException( PyExc_IndexError, "Index out of range");
}
/////////////////////////////////////////////////////////////////////////////////
@ -243,109 +218,110 @@ struct SubRegister {
/////////////////////////////////////////////////////////////////////////////////
static const class SubRegisterMapI386 : public std::map<ULONG, SubRegister> {
public:
SubRegisterMapI386();
} g_SubRegistersI386;
/////////////////////////////////////////////////////////////////////////////////
struct SubRegisterMapI386 {
SubRegisterMapI386::SubRegisterMapI386()
std::map<ULONG, SubRegister> subRegs;
SubRegisterMapI386()
{
(*this)[CV_REG_AL].set(CV_REG_EAX, 0x00, 0xff);
(*this)[CV_REG_CL].set(CV_REG_ECX, 0x00, 0xff);
(*this)[CV_REG_DL].set(CV_REG_EDX, 0x00, 0xff);
(*this)[CV_REG_BL].set(CV_REG_EBX, 0x00, 0xff);
subRegs[CV_REG_AL].set(CV_REG_EAX, 0x00, 0xff);
subRegs[CV_REG_CL].set(CV_REG_ECX, 0x00, 0xff);
subRegs[CV_REG_DL].set(CV_REG_EDX, 0x00, 0xff);
subRegs[CV_REG_BL].set(CV_REG_EBX, 0x00, 0xff);
(*this)[CV_REG_AH].set(CV_REG_EAX, 0x08, 0xff);
(*this)[CV_REG_CH].set(CV_REG_ECX, 0x08, 0xff);
(*this)[CV_REG_DH].set(CV_REG_EDX, 0x08, 0xff);
(*this)[CV_REG_BH].set(CV_REG_EBX, 0x08, 0xff);
subRegs[CV_REG_AH].set(CV_REG_EAX, 0x08, 0xff);
subRegs[CV_REG_CH].set(CV_REG_ECX, 0x08, 0xff);
subRegs[CV_REG_DH].set(CV_REG_EDX, 0x08, 0xff);
subRegs[CV_REG_BH].set(CV_REG_EBX, 0x08, 0xff);
(*this)[CV_REG_AX].set(CV_REG_EAX, 0x00, 0xffff);
(*this)[CV_REG_CX].set(CV_REG_ECX, 0x00, 0xffff);
(*this)[CV_REG_DX].set(CV_REG_EDX, 0x00, 0xffff);
(*this)[CV_REG_BX].set(CV_REG_EBX, 0x00, 0xffff);
(*this)[CV_REG_SP].set(CV_REG_ESP, 0x00, 0xffff);
(*this)[CV_REG_BP].set(CV_REG_EBP, 0x00, 0xffff);
(*this)[CV_REG_SI].set(CV_REG_ESI, 0x00, 0xffff);
(*this)[CV_REG_DI].set(CV_REG_EDI, 0x00, 0xffff);
subRegs[CV_REG_AX].set(CV_REG_EAX, 0x00, 0xffff);
subRegs[CV_REG_CX].set(CV_REG_ECX, 0x00, 0xffff);
subRegs[CV_REG_DX].set(CV_REG_EDX, 0x00, 0xffff);
subRegs[CV_REG_BX].set(CV_REG_EBX, 0x00, 0xffff);
subRegs[CV_REG_SP].set(CV_REG_ESP, 0x00, 0xffff);
subRegs[CV_REG_BP].set(CV_REG_EBP, 0x00, 0xffff);
subRegs[CV_REG_SI].set(CV_REG_ESI, 0x00, 0xffff);
subRegs[CV_REG_DI].set(CV_REG_EDI, 0x00, 0xffff);
}
/////////////////////////////////////////////////////////////////////////////////
};
static const class SubRegisterMapAmd64 : public std::map<ULONG, SubRegister> {
public:
SubRegisterMapAmd64();
} g_SubRegistersAmd64;
static const std::map<ULONG, SubRegister> g_SubRegistersI386 = SubRegisterMapI386().subRegs;
/////////////////////////////////////////////////////////////////////////////////
SubRegisterMapAmd64::SubRegisterMapAmd64()
struct SubRegisterMapAmd64 {
std::map<ULONG, SubRegister> subRegs;
SubRegisterMapAmd64()
{
(*this)[CV_AMD64_AL].set(CV_AMD64_RAX, 0x00, 0xff);
(*this)[CV_AMD64_CL].set(CV_AMD64_RCX, 0x00, 0xff);
(*this)[CV_AMD64_DL].set(CV_AMD64_RDX, 0x00, 0xff);
(*this)[CV_AMD64_BL].set(CV_AMD64_RBX, 0x00, 0xff);
subRegs[CV_AMD64_AL].set(CV_AMD64_RAX, 0x00, 0xff);
subRegs[CV_AMD64_CL].set(CV_AMD64_RCX, 0x00, 0xff);
subRegs[CV_AMD64_DL].set(CV_AMD64_RDX, 0x00, 0xff);
subRegs[CV_AMD64_BL].set(CV_AMD64_RBX, 0x00, 0xff);
(*this)[CV_AMD64_AH].set(CV_AMD64_RAX, 0x08, 0xff);
(*this)[CV_AMD64_CH].set(CV_AMD64_RCX, 0x08, 0xff);
(*this)[CV_AMD64_DH].set(CV_AMD64_RDX, 0x08, 0xff);
(*this)[CV_AMD64_BH].set(CV_AMD64_RBX, 0x08, 0xff);
subRegs[CV_AMD64_AH].set(CV_AMD64_RAX, 0x08, 0xff);
subRegs[CV_AMD64_CH].set(CV_AMD64_RCX, 0x08, 0xff);
subRegs[CV_AMD64_DH].set(CV_AMD64_RDX, 0x08, 0xff);
subRegs[CV_AMD64_BH].set(CV_AMD64_RBX, 0x08, 0xff);
(*this)[CV_AMD64_AX].set(CV_AMD64_RAX, 0x00, 0xffff);
(*this)[CV_AMD64_CX].set(CV_AMD64_RCX, 0x00, 0xffff);
(*this)[CV_AMD64_DX].set(CV_AMD64_RDX, 0x00, 0xffff);
(*this)[CV_AMD64_BX].set(CV_AMD64_RBX, 0x00, 0xffff);
subRegs[CV_AMD64_AX].set(CV_AMD64_RAX, 0x00, 0xffff);
subRegs[CV_AMD64_CX].set(CV_AMD64_RCX, 0x00, 0xffff);
subRegs[CV_AMD64_DX].set(CV_AMD64_RDX, 0x00, 0xffff);
subRegs[CV_AMD64_BX].set(CV_AMD64_RBX, 0x00, 0xffff);
(*this)[CV_AMD64_SP].set(CV_AMD64_RSP, 0x00, 0xffff);
(*this)[CV_AMD64_BP].set(CV_AMD64_RBP, 0x00, 0xffff);
(*this)[CV_AMD64_SI].set(CV_AMD64_RSI, 0x00, 0xffff);
(*this)[CV_AMD64_DI].set(CV_AMD64_RDI, 0x00, 0xffff);
subRegs[CV_AMD64_SP].set(CV_AMD64_RSP, 0x00, 0xffff);
subRegs[CV_AMD64_BP].set(CV_AMD64_RBP, 0x00, 0xffff);
subRegs[CV_AMD64_SI].set(CV_AMD64_RSI, 0x00, 0xffff);
subRegs[CV_AMD64_DI].set(CV_AMD64_RDI, 0x00, 0xffff);
(*this)[CV_AMD64_EAX].set(CV_AMD64_RAX, 0x00, 0xffffffff);
(*this)[CV_AMD64_ECX].set(CV_AMD64_RCX, 0x00, 0xffffffff);
(*this)[CV_AMD64_EDX].set(CV_AMD64_RDX, 0x00, 0xffffffff);
(*this)[CV_AMD64_EBX].set(CV_AMD64_RBX, 0x00, 0xffffffff);
subRegs[CV_AMD64_EAX].set(CV_AMD64_RAX, 0x00, 0xffffffff);
subRegs[CV_AMD64_ECX].set(CV_AMD64_RCX, 0x00, 0xffffffff);
subRegs[CV_AMD64_EDX].set(CV_AMD64_RDX, 0x00, 0xffffffff);
subRegs[CV_AMD64_EBX].set(CV_AMD64_RBX, 0x00, 0xffffffff);
(*this)[CV_AMD64_ESP].set(CV_AMD64_RSP, 0x00, 0xffffffff);
(*this)[CV_AMD64_EBP].set(CV_AMD64_RBP, 0x00, 0xffffffff);
(*this)[CV_AMD64_ESI].set(CV_AMD64_RSI, 0x00, 0xffffffff);
(*this)[CV_AMD64_EDI].set(CV_AMD64_RDI, 0x00, 0xffffffff);
subRegs[CV_AMD64_ESP].set(CV_AMD64_RSP, 0x00, 0xffffffff);
subRegs[CV_AMD64_EBP].set(CV_AMD64_RBP, 0x00, 0xffffffff);
subRegs[CV_AMD64_ESI].set(CV_AMD64_RSI, 0x00, 0xffffffff);
subRegs[CV_AMD64_EDI].set(CV_AMD64_RDI, 0x00, 0xffffffff);
(*this)[CV_AMD64_R8B].set(CV_AMD64_R8, 0x00, 0xff);
(*this)[CV_AMD64_R9B].set(CV_AMD64_R9, 0x00, 0xff);
(*this)[CV_AMD64_R10B].set(CV_AMD64_R10, 0x00, 0xff);
(*this)[CV_AMD64_R11B].set(CV_AMD64_R11, 0x00, 0xff);
(*this)[CV_AMD64_R12B].set(CV_AMD64_R12, 0x00, 0xff);
(*this)[CV_AMD64_R13B].set(CV_AMD64_R13, 0x00, 0xff);
(*this)[CV_AMD64_R14B].set(CV_AMD64_R14, 0x00, 0xff);
(*this)[CV_AMD64_R15B].set(CV_AMD64_R15, 0x00, 0xff);
subRegs[CV_AMD64_R8B].set(CV_AMD64_R8, 0x00, 0xff);
subRegs[CV_AMD64_R9B].set(CV_AMD64_R9, 0x00, 0xff);
subRegs[CV_AMD64_R10B].set(CV_AMD64_R10, 0x00, 0xff);
subRegs[CV_AMD64_R11B].set(CV_AMD64_R11, 0x00, 0xff);
subRegs[CV_AMD64_R12B].set(CV_AMD64_R12, 0x00, 0xff);
subRegs[CV_AMD64_R13B].set(CV_AMD64_R13, 0x00, 0xff);
subRegs[CV_AMD64_R14B].set(CV_AMD64_R14, 0x00, 0xff);
subRegs[CV_AMD64_R15B].set(CV_AMD64_R15, 0x00, 0xff);
(*this)[CV_AMD64_R8W].set(CV_AMD64_R8, 0x00, 0xffff);
(*this)[CV_AMD64_R9W].set(CV_AMD64_R9, 0x00, 0xffff);
(*this)[CV_AMD64_R10W].set(CV_AMD64_R10, 0x00, 0xffff);
(*this)[CV_AMD64_R11W].set(CV_AMD64_R11, 0x00, 0xffff);
(*this)[CV_AMD64_R12W].set(CV_AMD64_R12, 0x00, 0xffff);
(*this)[CV_AMD64_R13W].set(CV_AMD64_R13, 0x00, 0xffff);
(*this)[CV_AMD64_R14W].set(CV_AMD64_R14, 0x00, 0xffff);
(*this)[CV_AMD64_R15W].set(CV_AMD64_R15, 0x00, 0xffff);
subRegs[CV_AMD64_R8W].set(CV_AMD64_R8, 0x00, 0xffff);
subRegs[CV_AMD64_R9W].set(CV_AMD64_R9, 0x00, 0xffff);
subRegs[CV_AMD64_R10W].set(CV_AMD64_R10, 0x00, 0xffff);
subRegs[CV_AMD64_R11W].set(CV_AMD64_R11, 0x00, 0xffff);
subRegs[CV_AMD64_R12W].set(CV_AMD64_R12, 0x00, 0xffff);
subRegs[CV_AMD64_R13W].set(CV_AMD64_R13, 0x00, 0xffff);
subRegs[CV_AMD64_R14W].set(CV_AMD64_R14, 0x00, 0xffff);
subRegs[CV_AMD64_R15W].set(CV_AMD64_R15, 0x00, 0xffff);
(*this)[CV_AMD64_R8D].set(CV_AMD64_R8, 0x00, 0xffffffff);
(*this)[CV_AMD64_R9D].set(CV_AMD64_R9, 0x00, 0xffffffff);
(*this)[CV_AMD64_R10D].set(CV_AMD64_R10, 0x00, 0xffffffff);
(*this)[CV_AMD64_R11D].set(CV_AMD64_R11, 0x00, 0xffffffff);
(*this)[CV_AMD64_R12D].set(CV_AMD64_R12, 0x00, 0xffffffff);
(*this)[CV_AMD64_R13D].set(CV_AMD64_R13, 0x00, 0xffffffff);
(*this)[CV_AMD64_R14D].set(CV_AMD64_R14, 0x00, 0xffffffff);
(*this)[CV_AMD64_R15D].set(CV_AMD64_R15, 0x00, 0xffffffff);
subRegs[CV_AMD64_R8D].set(CV_AMD64_R8, 0x00, 0xffffffff);
subRegs[CV_AMD64_R9D].set(CV_AMD64_R9, 0x00, 0xffffffff);
subRegs[CV_AMD64_R10D].set(CV_AMD64_R10, 0x00, 0xffffffff);
subRegs[CV_AMD64_R11D].set(CV_AMD64_R11, 0x00, 0xffffffff);
subRegs[CV_AMD64_R12D].set(CV_AMD64_R12, 0x00, 0xffffffff);
subRegs[CV_AMD64_R13D].set(CV_AMD64_R13, 0x00, 0xffffffff);
subRegs[CV_AMD64_R14D].set(CV_AMD64_R14, 0x00, 0xffffffff);
subRegs[CV_AMD64_R15D].set(CV_AMD64_R15, 0x00, 0xffffffff);
}
};
static const std::map<ULONG, SubRegister> g_SubRegistersAmd64 = SubRegisterMapAmd64().subRegs;
/////////////////////////////////////////////////////////////////////////////////
ULONG64 Registers::getSubValue(ULONG cvRegId) const
bool ThreadContext::getSubValue(ULONG cvRegId, ULONG64 &val) const
{
const std::map<ULONG, SubRegister> *subRegs = NULL;
if (IMAGE_FILE_MACHINE_I386 == m_processorType)
@ -356,18 +332,17 @@ ULONG64 Registers::getSubValue(ULONG cvRegId) const
std::map<ULONG, SubRegister>::const_iterator itSubReg =
subRegs->find(cvRegId);
if (itSubReg == subRegs->end())
throw IsNotSubRegister();
return false;
RegValues::const_iterator itFullReg = m_regValues.find(itSubReg->second.m_fromReg);
if (itFullReg == m_regValues.end())
throw Exception(__FUNCTION__ ": Register missing");
return false;
return
(itFullReg->second >> itSubReg->second.m_bitsShift) & itSubReg->second.m_bitsMask;
}
// ----------------------------------------------------------------------------
val = (itFullReg->second >> itSubReg->second.m_bitsShift) & itSubReg->second.m_bitsMask;
return true;
}
/////////////////////////////////////////////////////////////////////////////////
}

View File

@ -1,31 +1,24 @@
#pragma once
#include <map>
#include <DbgEng.h>
#include <CvConst.h>
#include "context.h"
#include "dbgobj.h"
#include "dbgexcept.h"
#pragma once
namespace pykd {
std::string processorToStr(ULONG processorMode);
}
namespace Ctx {
////////////////////////////////////////////////////////////////////////////////
typedef pykd::DbgException Exception;
////////////////////////////////////////////////////////////////////////////////
class Registers
class ThreadContext : private DbgObject
{
public:
Registers(
IDebugControl4 *control,
IDebugAdvanced2 *advanced
);
ThreadContext( IDebugClient4 *client );
// get register value by ID
ULONG64 getValue(ULONG cvRegId) const;
@ -44,6 +37,7 @@ public:
ULONG getCount() const {
return static_cast<ULONG>( m_regValues.size() );
}
python::object getByIndex(ULONG ind) const;
// get processor type
@ -53,22 +47,14 @@ public:
private:
struct IsNotSubRegister : public std::exception {
IsNotSubRegister() : std::exception("is not sub-register") { }
};
// query i386 registers
void getI386Context(
IDebugAdvanced2 *advanced
);
void getI386Context();
// query AMD64 registers
void getAmd64Context(
IDebugAdvanced2 *advanced
);
void getAmd64Context();
// try query as "sub-register"
ULONG64 getSubValue(ULONG cvRegId) const;
bool getSubValue(ULONG cvRegId, ULONG64 &val) const;
private:
typedef std::map<ULONG, ULONG64> RegValues;
@ -79,7 +65,7 @@ private:
////////////////////////////////////////////////////////////////////////////////
typedef boost::shared_ptr< Registers > ContextPtr;
typedef boost::shared_ptr< ThreadContext > ContextPtr;
////////////////////////////////////////////////////////////////////////////////

View File

@ -7,64 +7,118 @@ namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
python::object DebugClient::getRegByIndex( ULONG index )
CpuReg::CpuReg( IDebugClient4 *client, const std::string &regName ) :
DbgObject( client )
{
HRESULT hres;
DEBUG_VALUE debugValue;
hres = m_registers->GetValue( index, &debugValue );
m_name = regName;
hres = m_registers->GetIndexByName( m_name.c_str(), &m_index );
if ( FAILED( hres ) )
throw DbgException( "IDebugRegister::GetValue failed" );
switch( debugValue.Type )
{
case DEBUG_VALUE_INT8:
return boost::python::long_( debugValue.I8 );
break;
case DEBUG_VALUE_INT16:
return boost::python::long_( debugValue.I16 );
break;
case DEBUG_VALUE_INT32:
return boost::python::long_( debugValue.I32 );
break;
case DEBUG_VALUE_INT64:
return boost::python::long_(debugValue.I64 );
break;
}
throw DbgException( "Invalid register value" );
}
python::object getRegByIndex( ULONG index )
{
return g_dbgClient->getRegByIndex( index );
throw DbgException( "IDebugRegister::GetIndexByName", hres );
}
///////////////////////////////////////////////////////////////////////////////////
python::object DebugClient::getRegByName( const std::wstring &regName )
CpuReg::CpuReg( IDebugClient4 *client, ULONG index ) :
DbgObject( client )
{
ULONG registerIndex = 0;
HRESULT hres;
hres = m_registers->GetIndexByNameWide( regName.c_str(), &registerIndex );
if ( FAILED( hres ) )
throw DbgException( "IDebugRegister2::GetIndexByNameWide failed" );
m_index = index;
ULONG nameSize = 0;
hres =
m_registers->GetDescription(
m_index,
NULL,
0,
&nameSize,
NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugRegister::GetDescription", hres );
std::vector<char> nameBuffer(nameSize);
hres =
m_registers->GetDescription(
m_index,
&nameBuffer[0],
nameSize,
NULL,
NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugRegister::GetDescription", hres );
m_name = std::string( &nameBuffer[0] );
return getRegByIndex( registerIndex );
}
python::object getRegByName( const std::wstring &regName )
///////////////////////////////////////////////////////////////////////////////////
BaseTypeVariant CpuReg::getValue()
{
HRESULT hres;
DEBUG_VALUE debugValue;
hres = m_registers->GetValue( m_index, &debugValue );
if ( FAILED( hres ) )
throw DbgException( "IDebugRegister::GetValue", hres );
switch( debugValue.Type )
{
case DEBUG_VALUE_INT8:
return BaseTypeVariant( (LONG)debugValue.I8 );
break;
case DEBUG_VALUE_INT16:
return BaseTypeVariant( (LONG)debugValue.I16 );
break;
case DEBUG_VALUE_INT32:
return BaseTypeVariant( debugValue.I32 );
break;
case DEBUG_VALUE_INT64:
return BaseTypeVariant( debugValue.I64 );
break;
}
throw DbgException( "Failed to convert register value" );
}
///////////////////////////////////////////////////////////////////////////////////
CpuReg DebugClient::getRegByName( const std::string &regName )
{
return CpuReg( m_client, regName );
}
CpuReg getRegByName( const std::string &regName )
{
return g_dbgClient->getRegByName( regName );
}
///////////////////////////////////////////////////////////////////////////////////
CpuReg DebugClient::getRegByIndex( ULONG index )
{
return CpuReg( m_client, index );
}
CpuReg getRegByIndex( ULONG index )
{
return g_dbgClient->getRegByIndex( index );
}
///////////////////////////////////////////////////////////////////////////////////
ULONG64 DebugClient::loadMSR( ULONG msr )
{
HRESULT hres;
@ -72,7 +126,7 @@ ULONG64 DebugClient::loadMSR( ULONG msr )
hres = m_dataSpaces->ReadMsr( msr, &value );
if ( FAILED( hres ) )
throw DbgException( "IDebugDataSpaces::ReadMsr failed" );
throw DbgException( "IDebugDataSpaces::ReadMsr", hres );
return value;
}
@ -90,7 +144,7 @@ void DebugClient::setMSR( ULONG msr, ULONG64 value)
hres = m_dataSpaces->WriteMsr(msr, value);
if ( FAILED( hres ) )
throw DbgException( "IDebugDataSpaces::WriteMsr failed" );
throw DbgException( "IDebugDataSpaces::WriteMsr", hres );
}
void setMSR( ULONG msr, ULONG64 value)

View File

@ -7,9 +7,37 @@ namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
python::object getRegByName( const std::wstring &regName );
class CpuReg : public intBase, protected DbgObject {
python::object getRegByIndex( ULONG index );
public:
CpuReg( IDebugClient4 *client, const std::string &regName );
CpuReg( IDebugClient4 *client, ULONG index );
std::string
name() const {
return m_name;
}
ULONG index() const {
return m_index;
}
virtual BaseTypeVariant getValue();
private:
std::string m_name;
ULONG m_index;
};
///////////////////////////////////////////////////////////////////////////////////
CpuReg getRegByName( const std::string &regName );
CpuReg getRegByIndex( ULONG index );
ULONG64 loadMSR( ULONG msr );

View File

@ -210,9 +210,9 @@ public:
void setMSR( ULONG msr, ULONG64 value);
python::object getRegByName( const std::wstring &regName );
CpuReg getRegByName( const std::string &regName );
python::object getRegByIndex( ULONG index );
CpuReg getRegByIndex( ULONG index );
void setCurrentProcess( ULONG64 addr );
@ -234,14 +234,12 @@ public:
return getDbgControl(GetPageSize);
}
Ctx::ContextPtr getThreadContext() {
return Ctx::ContextPtr(
new Ctx::Registers(m_control, m_advanced)
);
ContextPtr getThreadContext() {
return ContextPtr( new ThreadContext(m_client) );
}
python::dict getLocals(
Ctx::ContextPtr ctx = Ctx::ContextPtr( reinterpret_cast<Ctx::Registers *>(0) )
ContextPtr ctx = ContextPtr( reinterpret_cast<ThreadContext*>(0) )
);
public:
@ -397,12 +395,12 @@ inline ULONG getPageSize() {
return g_dbgClient->getPageSize();
}
inline Ctx::ContextPtr getThreadContext() {
inline ContextPtr getThreadContext() {
return g_dbgClient->getThreadContext();
}
inline python::dict getLocals(
Ctx::ContextPtr ctx = Ctx::ContextPtr( reinterpret_cast<Ctx::Registers *>(0) )
ContextPtr ctx = ContextPtr()
)
{
return g_dbgClient->getLocals(ctx);

View File

@ -143,7 +143,8 @@ BOOST_PYTHON_MODULE( pykd )
.def( "__long__", &intBase::long_ )
.def( "__int__", &intBase::int_ )
.def( "__index__", &intBase::long_ )
.def( "__hash__", &intBase::long_ );
.def( "__hash__", &intBase::long_ )
.def( "__coerce__", &intBase::coerce );
python::class_<DebugClient, DebugClientPtr>("dbgClient", "Class representing a debugging session", python::no_init )
.def( "addr64", &DebugClient::addr64,
@ -612,23 +613,28 @@ BOOST_PYTHON_MODULE( pykd )
.def_readonly( "frameNumber", &DEBUG_STACK_FRAME::FrameNumber,
"Return a frame's number" );
python::class_<Ctx::Registers, Ctx::ContextPtr>(
python::class_<ThreadContext, ContextPtr>(
"Context", "Context of thread (register values)", python::no_init )
.def( "ip", &Ctx::Registers::getIp,
.def( "ip", &ThreadContext::getIp,
"Get instruction pointer register" )
.def( "retreg", &Ctx::Registers::getIp,
.def( "retreg", &ThreadContext::getIp,
"Get primary return value register" )
.def( "csp", &Ctx::Registers::getSp,
.def( "csp", &ThreadContext::getSp,
"Get current stack pointer" )
.def( "get", &Ctx::Registers::getValue,
.def( "get", &ThreadContext::getValue,
"Get register value by ID (CV_REG_XXX)" )
.def( "processorType", &Ctx::Registers::getProcessorType,
"Get processor type as string")
.def("__len__", &Ctx::Registers::getCount,
.def( "processorType", &ThreadContext::getProcessorType,
"Get processor ThreadContext as string")
.def("__len__", &ThreadContext::getCount,
"Return count of registers")
.def("__getitem__", &Ctx::Registers::getByIndex,
.def("__getitem__", &ThreadContext::getByIndex,
"Return tuple<ID, VALUE> by index");
python::class_<CpuReg, python::bases<intBase> >(
"cpuReg", "CPU regsiter class", boost::python::no_init )
.def( "name", &CpuReg::name, "The name of the regsiter" )
.def( "index", &CpuReg::index, "The index of thr register" );
python::def( "diaLoadPdb", &pyDia::GlobalScope::loadPdb,
"Open pdb file for querying debug symbols. Return DiaSymbol of global scope");

View File

@ -185,6 +185,11 @@ public:
return boost::apply_visitor( VariantToPyobj(), getValue() ) != 0;
}
python::object coerce() {
__debugbreak();
return python::object();
}
private:
virtual BaseTypeVariant getValue() {

View File

@ -19,7 +19,7 @@ struct addLocals {
python::dict &m_locals;
const Module &m_module;
ULONG m_rva;
Ctx::ContextPtr m_ctx;
ContextPtr m_ctx;
IDebugClient4 *m_client;
ULONG m_formalNameCounter;
@ -181,7 +181,7 @@ static bool isOutOfDebugRange(
////////////////////////////////////////////////////////////////////////////////
python::dict DebugClient::getLocals(Ctx::ContextPtr ctx OPTIONAL)
python::dict DebugClient::getLocals(ContextPtr ctx OPTIONAL)
{
if (!ctx)
ctx = getThreadContext();

View File

@ -1,11 +1,14 @@
#define PYKD_VERSION_MAJOR 0
#define PYKD_VERSION_MINOR 1
#define PYKD_VERSION_SUBVERSION 0
#define PYKD_VERSION_BUILDNO 6
#define __VER_STR2__(x) #x
#define __VER_STR1__(x) __VER_STR2__(x)
#define PYKD_VERSION_MAJOR 1
#define PYKD_VERSION_MINOR 6
#define PYKD_VERSION_BUILD 0,PYKD_VERSION_MAJOR,0,PYKD_VERSION_MINOR
#define PYKD_VERSION_BUILD PYKD_VERSION_MAJOR, PYKD_VERSION_MINOR, PYKD_VERSION_SUBVERSION, PYKD_VERSION_BUILDNO
#define PYKD_VERSION_BUILD_STR __VER_STR1__(PYKD_VERSION_BUILD)