[0.1.x] changed: method __getitem__ (index) of the Context class returns tuple <REG_ID, REG_NAME, REG_VALUE>

[0.1.x] added: method __getitem__ (regName) of the Context class
[0.1.x] added: method __getattr__ (regName) of the Context class
[0.1.x] added: method __str__() of the Context class

git-svn-id: https://pykd.svn.codeplex.com/svn@76867 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-06-01 15:26:51 +00:00 committed by Mikhail I. Izmestev
parent 0fca2e7aa3
commit a7e9463dc4
3 changed files with 97 additions and 4 deletions

View File

@ -2,6 +2,7 @@
#include "stdafx.h" #include "stdafx.h"
#include <boost\python\tuple.hpp> #include <boost\python\tuple.hpp>
#include <boost\algorithm\string\case_conv.hpp>
#include "context.h" #include "context.h"
#include "stkframe.h" #include "stkframe.h"
@ -145,6 +146,32 @@ ULONG64 ThreadContext::getValue(ULONG cvRegId) const
throw DbgException(__FUNCTION__ ": Register missing"); throw DbgException(__FUNCTION__ ": Register missing");
} }
/////////////////////////////////////////////////////////////////////////////////
ULONG64 ThreadContext::getValueByName( const std::string &regName ) const
{
std::string upcaseName = boost::to_upper_copy( regName );
if ( IMAGE_FILE_MACHINE_I386 == m_processorType )
{
for ( ULONG i = 0; i < pyDia::Symbol::cntI386RegName; ++i )
{
if ( upcaseName == pyDia::Symbol::i386RegName[i].second )
return getValue( pyDia::Symbol::i386RegName[i].first );
}
}
else
{
for ( ULONG i = 0; i < pyDia::Symbol::cntAmd64RegName; ++i )
{
if ( upcaseName == pyDia::Symbol::amd64RegName[i].second )
return getValue( pyDia::Symbol::amd64RegName[i].first );
}
}
throwUnsupportedProcessor(__FUNCTION__);
}
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
bool ThreadContext::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const bool ThreadContext::getValueNoThrow(ULONG cvRegId, ULONG64 &val) const
@ -218,7 +245,27 @@ python::object ThreadContext::getByIndex(ULONG ind) const
for (ULONG i = 0; it != m_regValues.end(); ++i, ++it ) for (ULONG i = 0; it != m_regValues.end(); ++i, ++it )
{ {
if (i == ind) if (i == ind)
return python::make_tuple(it->first, it->second); {
switch (m_processorType)
{
case IMAGE_FILE_MACHINE_I386:
for ( ULONG j = 0; j < pyDia::Symbol::cntI386RegName; ++j )
if ( pyDia::Symbol::i386RegName[j].first == it->first )
return python::make_tuple( it->first, pyDia::Symbol::i386RegName[j].second, it->second);
break;
case IMAGE_FILE_MACHINE_AMD64:
for ( ULONG j = 0; j < pyDia::Symbol::cntAmd64RegName; ++j )
if ( pyDia::Symbol::amd64RegName[j].first == it->first )
return python::make_tuple( it->first, pyDia::Symbol::amd64RegName[j].second, it->second);
break;
}
}
} }
throw PyException( PyExc_IndexError, "Index out of range"); throw PyException( PyExc_IndexError, "Index out of range");
@ -376,4 +423,38 @@ void ThreadContext::throwUnsupportedProcessor(PCSTR szFunction) const
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
std::string ThreadContext::print() const
{
std::stringstream sstr;
RegValues::const_iterator it = m_regValues.begin();
for (; it != m_regValues.end(); ++it )
{
switch (m_processorType)
{
case IMAGE_FILE_MACHINE_I386:
for ( ULONG j = 0; j < pyDia::Symbol::cntI386RegName; ++j )
if ( pyDia::Symbol::i386RegName[j].first == it->first )
sstr << pyDia::Symbol::i386RegName[j].second << '=' << std::hex << it->second << std::endl;
break;
case IMAGE_FILE_MACHINE_AMD64:
for ( ULONG j = 0; j < pyDia::Symbol::cntAmd64RegName; ++j )
if ( pyDia::Symbol::amd64RegName[j].first == it->first )
sstr << pyDia::Symbol::amd64RegName[j].second << '=' << std::hex << it->second << std::endl;
break;
}
}
return sstr.str();
}
/////////////////////////////////////////////////////////////////////////////////
} }

View File

@ -30,6 +30,7 @@ public:
// get register value by ID // get register value by ID
ULONG64 getValue(ULONG cvRegId) const; ULONG64 getValue(ULONG cvRegId) const;
ULONG64 getValueByName( const std::string &regName ) const;
bool getValueNoThrow(ULONG cvRegId, ULONG64 &val) const; bool getValueNoThrow(ULONG cvRegId, ULONG64 &val) const;
// get @$ip pseudo register // get @$ip pseudo register
@ -55,6 +56,8 @@ public:
ContextPtr forkByStackFrame(const StackFrame &stkFrmae) const; ContextPtr forkByStackFrame(const StackFrame &stkFrmae) const;
std::string print() const;
private: private:
// query i386 registers // query i386 registers

View File

@ -680,7 +680,7 @@ BOOST_PYTHON_MODULE( pykd )
.def( "getLocals", &StackFrame::getLocals, StackFrame_getLocals( python::args( "ctx" ), .def( "getLocals", &StackFrame::getLocals, StackFrame_getLocals( python::args( "ctx" ),
"Get list of local variables for this stack frame" ) ) "Get list of local variables for this stack frame" ) )
.def( "__str__", &StackFrame::print, .def( "__str__", &StackFrame::print,
"Return stacks frame as string"); "Return stacks frame as a string");
python::class_<ThreadContext, ContextPtr>( python::class_<ThreadContext, ContextPtr>(
"Context", "Context of thread (register values)", python::no_init ) "Context", "Context of thread (register values)", python::no_init )
@ -692,6 +692,8 @@ BOOST_PYTHON_MODULE( pykd )
"Get current stack pointer" ) "Get current stack pointer" )
.def( "get", &ThreadContext::getValue, .def( "get", &ThreadContext::getValue,
"Get register value by ID (CV_REG_XXX)" ) "Get register value by ID (CV_REG_XXX)" )
.def( "get", &ThreadContext::getValueByName,
"Get register value by name" )
.def( "processorType", &ThreadContext::getProcessorType, .def( "processorType", &ThreadContext::getProcessorType,
"Get processor ThreadContext as string") "Get processor ThreadContext as string")
.def( "fork", &ThreadContext::forkByStackFrame, .def( "fork", &ThreadContext::forkByStackFrame,
@ -699,7 +701,14 @@ BOOST_PYTHON_MODULE( pykd )
.def("__len__", &ThreadContext::getCount, .def("__len__", &ThreadContext::getCount,
"Return count of registers") "Return count of registers")
.def("__getitem__", &ThreadContext::getByIndex, .def("__getitem__", &ThreadContext::getByIndex,
"Return tuple<ID, VALUE> by index"); "Return tuple<ID, NAME, VALUE> by index")
.def("__getitem__", &ThreadContext::getValueByName,
"Return register value by name" )
.def("__getattr__", &ThreadContext::getValueByName,
"Return register value as a attribute of the Context" )
.def("__str__", &ThreadContext::print,
"Return context as a string" );
python::class_<CpuReg, python::bases<intBase> >( python::class_<CpuReg, python::bases<intBase> >(
"cpuReg", "CPU regsiter class", boost::python::no_init ) "cpuReg", "CPU regsiter class", boost::python::no_init )