[+] pyDia: dicts {cv-const: "cv-const-name"}, get type of array index, query basic types

git-svn-id: https://pykd.svn.codeplex.com/svn@69903 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\EreTIk_cp 2011-09-20 22:17:40 +00:00 committed by Mikhail I. Izmestev
parent e19c2df872
commit 4ecd871b02
3 changed files with 227 additions and 98 deletions

View File

@ -73,6 +73,16 @@ pycmd( PDEBUG_CLIENT4 client, PCSTR args )
////////////////////////////////////////////////////////////////////////////////
static python::dict genDict(const pyDia::Symbol::ValueNameEntry srcValues[], size_t cntValues)
{
python::dict resDict;
for (size_t i = 0; i < cntValues; ++i)
resDict[srcValues[i].first] = srcValues[i].second;
return resDict;
}
////////////////////////////////////////////////////////////////////////////////
#define DEF_PY_CONST_ULONG(x) \
python::scope().attr(#x) = ULONG(##x)
@ -94,7 +104,6 @@ BOOST_PYTHON_MODULE( pykd )
"Return size of the module" )
.def("name", &pykd::Module::getName,
"Return name of the module" );
python::def( "diaOpenPdb", &pyDia::GlobalScope::openPdb,
"Open pdb file for quering debug symbols. Return DiaSymbol of global scope");
@ -110,6 +119,8 @@ BOOST_PYTHON_MODULE( pykd )
"Retrieves the name of the symbol" )
.def( "type", &pyDia::Symbol::getType,
"Retrieves the symbol that represents the type for this symbol" )
.def( "indexType", &pyDia::Symbol::getIndexType,
"Retrieves the symbol interface of the array index type of the symbol" )
.def( "rva", &pyDia::Symbol::getRva,
"Retrieves the relative virtual address (RVA) of the location")
.def( "symTag", &pyDia::Symbol::getSymTag,
@ -118,8 +129,12 @@ BOOST_PYTHON_MODULE( pykd )
"Retrieves the location type of a data symbol: LocIsXxx" )
.def( "value", &pyDia::Symbol::getValue,
"Retrieves the value of a constant")
.def( "isBasic", &pyDia::Symbol::isBasicType,
"Retrieves a flag of basic type for symbol")
.def( "baseType", &pyDia::Symbol::getBaseType,
"Retrieves the base type for this symbol")
.def( "__str__", &pyDia::Symbol::print)
.def("__getattr__", &pyDia::Symbol::getChildByName)
// .def("__getattr__", &pyDia::Symbol::getChildByName)
.def("__len__", &pyDia::Symbol::getChildCount )
.def("__getitem__", &pyDia::Symbol::getChildByIndex);
@ -157,6 +172,8 @@ BOOST_PYTHON_MODULE( pykd )
DEF_PY_CONST_ULONG(SymTagCustomType);
DEF_PY_CONST_ULONG(SymTagManagedType);
DEF_PY_CONST_ULONG(SymTagDimension);
python::scope().attr("diaSymTagName") =
genDict(pyDia::Symbol::symTagName, _countof(pyDia::Symbol::symTagName));
// search options for symbol and file names
DEF_PY_CONST_ULONG(nsfCaseSensitive);
@ -182,6 +199,29 @@ BOOST_PYTHON_MODULE( pykd )
DEF_PY_CONST_ULONG(LocIsIlRel);
DEF_PY_CONST_ULONG(LocInMetaData);
DEF_PY_CONST_ULONG(LocIsConstant);
python::scope().attr("diaLocTypeName") =
genDict(pyDia::Symbol::symTagName, _countof(pyDia::Symbol::locTypeName));
DEF_PY_CONST_ULONG(btNoType);
DEF_PY_CONST_ULONG(btVoid);
DEF_PY_CONST_ULONG(btChar);
DEF_PY_CONST_ULONG(btWChar);
DEF_PY_CONST_ULONG(btInt);
DEF_PY_CONST_ULONG(btUInt);
DEF_PY_CONST_ULONG(btFloat);
DEF_PY_CONST_ULONG(btBCD);
DEF_PY_CONST_ULONG(btBool);
DEF_PY_CONST_ULONG(btLong);
DEF_PY_CONST_ULONG(btULong);
DEF_PY_CONST_ULONG(btCurrency);
DEF_PY_CONST_ULONG(btDate);
DEF_PY_CONST_ULONG(btVariant);
DEF_PY_CONST_ULONG(btComplex);
DEF_PY_CONST_ULONG(btBit);
DEF_PY_CONST_ULONG(btBSTR);
DEF_PY_CONST_ULONG(btHresult);
python::scope().attr("diaBasicType") =
genDict(pyDia::Symbol::basicTypeName, pyDia::Symbol::cntBasicTypeName);
// exception:
// base exception

View File

@ -17,53 +17,117 @@ const std::string Exception::descPrefix("pyDia: ");
////////////////////////////////////////////////////////////////////////////////
const char *Symbol::symTagName[SymTagMax] = {
"Null",
"Exe",
"Compiland",
"CompilandDetails",
"CompilandEnv",
"Function",
"Block",
"Data",
"Annotation",
"Label",
"PublicSymbol",
"UDT",
"Enum",
"FunctionType",
"PointerType",
"ArrayType",
"BaseType",
"Typedef",
"BaseClass",
"Friend",
"FunctionArgType",
"FuncDebugStart",
"FuncDebugEnd",
"UsingNamespace",
"VTableShape",
"VTable",
"Custom",
"Thunk",
"CustomType",
"ManagedType",
"Dimension"
#define _DEF_SYM_TAG_VAL(x) Symbol::ValueNameEntry(SymTag##x, #x)
const Symbol::ValueNameEntry Symbol::symTagName[SymTagMax] = {
_DEF_SYM_TAG_VAL(Null),
_DEF_SYM_TAG_VAL(Exe),
_DEF_SYM_TAG_VAL(Compiland),
_DEF_SYM_TAG_VAL(CompilandDetails),
_DEF_SYM_TAG_VAL(CompilandEnv),
_DEF_SYM_TAG_VAL(Function),
_DEF_SYM_TAG_VAL(Block),
_DEF_SYM_TAG_VAL(Data),
_DEF_SYM_TAG_VAL(Annotation),
_DEF_SYM_TAG_VAL(Label),
_DEF_SYM_TAG_VAL(PublicSymbol),
_DEF_SYM_TAG_VAL(UDT),
_DEF_SYM_TAG_VAL(Enum),
_DEF_SYM_TAG_VAL(FunctionType),
_DEF_SYM_TAG_VAL(PointerType),
_DEF_SYM_TAG_VAL(ArrayType),
_DEF_SYM_TAG_VAL(BaseType),
_DEF_SYM_TAG_VAL(Typedef),
_DEF_SYM_TAG_VAL(BaseClass),
_DEF_SYM_TAG_VAL(Friend),
_DEF_SYM_TAG_VAL(FunctionArgType),
_DEF_SYM_TAG_VAL(FuncDebugStart),
_DEF_SYM_TAG_VAL(FuncDebugEnd),
_DEF_SYM_TAG_VAL(UsingNamespace),
_DEF_SYM_TAG_VAL(VTableShape),
_DEF_SYM_TAG_VAL(VTable),
_DEF_SYM_TAG_VAL(Custom),
_DEF_SYM_TAG_VAL(Thunk),
_DEF_SYM_TAG_VAL(CustomType),
_DEF_SYM_TAG_VAL(ManagedType),
_DEF_SYM_TAG_VAL(Dimension)
};
#undef _DEF_SYM_TAG_VAL
const char *Symbol::locTypeName[LocTypeMax] = {
"Null",
"Static",
"TLS",
"RegRel",
"ThisRel",
"Enregistered",
"BitField",
"Slot",
"IlRel",
"InMetaData",
"Constant"
#define _DEF_LOC_TYPE(x) Symbol::ValueNameEntry(LocIs##x, #x)
const Symbol::ValueNameEntry Symbol::locTypeName[LocTypeMax] = {
_DEF_LOC_TYPE(Null),
_DEF_LOC_TYPE(Static),
_DEF_LOC_TYPE(TLS),
_DEF_LOC_TYPE(RegRel),
_DEF_LOC_TYPE(ThisRel),
_DEF_LOC_TYPE(Enregistered),
_DEF_LOC_TYPE(BitField),
_DEF_LOC_TYPE(Slot),
_DEF_LOC_TYPE(IlRel),
Symbol::ValueNameEntry(LocInMetaData, "InMetaData"),
_DEF_LOC_TYPE(Constant)
};
#undef _DEF_LOC_TYPE
#define _DEF_BASIC_TYPE(x) Symbol::ValueNameEntry(bt##x, #x)
const Symbol::ValueNameEntry Symbol::basicTypeName[] = {
_DEF_BASIC_TYPE(NoType),
_DEF_BASIC_TYPE(Void),
_DEF_BASIC_TYPE(Char),
_DEF_BASIC_TYPE(WChar),
_DEF_BASIC_TYPE(Int),
_DEF_BASIC_TYPE(UInt),
_DEF_BASIC_TYPE(Float),
_DEF_BASIC_TYPE(BCD),
_DEF_BASIC_TYPE(Bool),
_DEF_BASIC_TYPE(Long),
_DEF_BASIC_TYPE(ULong),
_DEF_BASIC_TYPE(Currency),
_DEF_BASIC_TYPE(Date),
_DEF_BASIC_TYPE(Variant),
_DEF_BASIC_TYPE(Complex),
_DEF_BASIC_TYPE(Bit),
_DEF_BASIC_TYPE(BSTR),
_DEF_BASIC_TYPE(Hresult)
};
#undef _DEF_BASIC_TYPE
const size_t Symbol::cntBasicTypeName = _countof(Symbol::basicTypeName);
////////////////////////////////////////////////////////////////////////////////
#define callSymbol(retType, method) \
do { \
throwIfNull(__FUNCTION__); \
retType retValue; \
HRESULT hres = m_symbol->##method(&retValue); \
if (FAILED(hres)) \
throw Exception("Call IDiaSymbol::" #method, hres); \
return retValue; \
} while(false)
#define callSymbolDword(method) callSymbol(DWORD, method)
#define callSymbolUlonglong(method) callSymbol(ULONGLONG, method)
#define callSymbolObjectFromSymbol(method) \
do { \
throwIfNull(__FUNCTION__); \
DiaSymbolPtr retSymbol; \
HRESULT hres = m_symbol->##method(&retSymbol); \
if (S_OK != hres) \
throw Exception("Call IDiaSymbol::" #method, hres); \
return python::object( Symbol(retSymbol) ); \
} while(false)
#define callSymbolStr(method) \
do { \
throwIfNull(__FUNCTION__); \
autoBstr bstrName; \
HRESULT hres = m_symbol->##method(&bstrName); \
if (S_OK != hres) \
throw Exception("Call IDiaSymbol" #method, hres); \
return bstrName.asStr(); \
} while(false)
////////////////////////////////////////////////////////////////////////////////
@ -139,84 +203,49 @@ python::list Symbol::findChildrenImpl(
ULONGLONG Symbol::getSize()
{
throwIfNull(__FUNCTION__);
ULONGLONG retValue;
HRESULT hres = m_symbol->get_length(&retValue);
if (S_OK != hres)
throw Exception("Call IDiaSymbol::get_length", hres);
return retValue;
callSymbolUlonglong(get_length);
}
////////////////////////////////////////////////////////////////////////////////
std::string Symbol::getName()
{
throwIfNull(__FUNCTION__);
autoBstr bstrName;
HRESULT hres = m_symbol->get_name(&bstrName);
if (S_OK != hres)
throw Exception("Call IDiaSymbol::get_name", hres);
return bstrName.asStr();
callSymbolStr(get_name);
}
////////////////////////////////////////////////////////////////////////////////
python::object Symbol::getType()
{
throwIfNull(__FUNCTION__);
callSymbolObjectFromSymbol(get_type);
}
DiaSymbolPtr _type;
HRESULT hres = m_symbol->get_type(&_type);
if (S_OK != hres)
throw Exception("Call IDiaSymbol::get_type", hres);
////////////////////////////////////////////////////////////////////////////////
return python::object( Symbol(_type) );
python::object Symbol::getIndexType()
{
callSymbolObjectFromSymbol(get_arrayIndexType);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getSymTag()
{
throwIfNull(__FUNCTION__);
DWORD retValue;
HRESULT hres = m_symbol->get_symTag(&retValue);
if (S_OK != hres)
throw Exception("Call IDiaSymbol::get_symTag", hres);
return retValue;
callSymbolDword(get_symTag);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getRva()
{
throwIfNull(__FUNCTION__);
DWORD retValue;
HRESULT hres = m_symbol->get_relativeVirtualAddress(&retValue);
if (S_OK != hres)
throw Exception("Call IDiaSymbol::get_relativeVirtualAddress", hres);
return retValue;
callSymbolDword(get_relativeVirtualAddress);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getLocType()
{
throwIfNull(__FUNCTION__);
DWORD retValue;
HRESULT hres = m_symbol->get_locationType(&retValue);
if (S_OK != hres)
throw Exception("Call IDiaSymbol::get_locationType", hres);
return retValue;
callSymbolDword(get_locationType);
}
////////////////////////////////////////////////////////////////////////////////
@ -270,6 +299,32 @@ python::object Symbol::getValue()
////////////////////////////////////////////////////////////////////////////////
bool Symbol::isBasicType()
{
throwIfNull(__FUNCTION__);
DWORD baseType = btNoType;
return
SUCCEEDED( m_symbol->get_baseType(&baseType) ) &&
(btNoType != baseType);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getBaseType()
{
callSymbolDword(get_baseType);
}
////////////////////////////////////////////////////////////////////////////////
ULONG Symbol::getBitPosition()
{
callSymbolDword(get_bitPosition);
}
////////////////////////////////////////////////////////////////////////////////
python::object Symbol::getChildByName(const std::string &_name)
{
throwIfNull(__FUNCTION__);
@ -373,7 +428,7 @@ std::string Symbol::print()
sstream << "symTag: ";
HRESULT hres = m_symbol->get_symTag(&dwValue);
if ((S_OK == hres) && dwValue < _countof(symTagName))
sstream << symTagName[dwValue];
sstream << symTagName[dwValue].second;
else
sstream << "<unknown>";
sstream << ", ";
@ -389,7 +444,7 @@ std::string Symbol::print()
if ((S_OK == hres) && dwValue < _countof(locTypeName))
{
sstream << std::endl;
sstream << "Location: " << locTypeName[dwValue];
sstream << "Location: " << locTypeName[dwValue].second;
if (dwValue == LocIsStatic)
{
hres = m_symbol->get_relativeVirtualAddress(&dwValue);
@ -452,6 +507,20 @@ std::string Symbol::print()
break;
}
}
hres = m_symbol->get_baseType(&dwValue);
if (SUCCEEDED(hres) && btNoType != dwValue)
{
for (ULONG i = 0; i < cntBasicTypeName; ++i)
{
if (basicTypeName[i].first == dwValue)
{
sstream << std::endl;
sstream << "Basic type is " << basicTypeName[i].second;
break;
}
}
}
}
return sstream.str();
}

View File

@ -70,33 +70,53 @@ public:
}
ULONGLONG getSize();
std::string getName();
python::object getType();
python::object getIndexType();
ULONG getSymTag();
ULONG getRva();
ULONG getLocType();
python::object getValue();
bool isBasicType();
ULONG getBaseType();
ULONG getBitPosition();
python::object getChildByName(const std::string &_name);
ULONG getChildCount();
python::object getChildByIndex(ULONG _index);
std::string print();
public:
typedef std::pair<ULONG, const char *> ValueNameEntry;
static const ValueNameEntry symTagName[SymTagMax];
static const ValueNameEntry locTypeName[LocTypeMax];
static const ValueNameEntry basicTypeName[];
static const size_t cntBasicTypeName;
protected:
void throwIfNull(const char *desc)
{
if (!m_symbol)
throw Exception(std::string(desc) + " failed, object not preinitialized");
throw Exception(std::string(desc) + " failed, DIA object is not initialized");
}
Symbol(__inout DiaSymbolPtr &_symbol) {
m_symbol = _symbol.Detach();
}
static const char *symTagName[SymTagMax];
static const char *locTypeName[LocTypeMax];
DiaSymbolPtr m_symbol;
};