mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-29 11:53:23 +08:00
748 lines
21 KiB
C++
748 lines
21 KiB
C++
|
||
#include "stdafx.h"
|
||
#include "dbghelp.h"
|
||
#include "dia/diawrapper.h"
|
||
#include "win/utils.h"
|
||
|
||
namespace pykd {
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
|
||
static const struct DiaRegToRegRelativeAmd64 : DiaRegToRegRelativeBase
|
||
{
|
||
typedef std::map<ULONG, ULONG> Base;
|
||
DiaRegToRegRelativeAmd64();
|
||
} g_DiaRegToRegRelativeAmd64;
|
||
|
||
DiaRegToRegRelativeAmd64::DiaRegToRegRelativeAmd64()
|
||
{
|
||
(*this)[CV_AMD64_RIP] = rriInstructionPointer;
|
||
(*this)[CV_AMD64_RBP] = rriStackFrame;
|
||
(*this)[CV_AMD64_RSP] = rriStackPointer;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
|
||
static const struct DiaRegToRegRelativeI386 : DiaRegToRegRelativeBase
|
||
{
|
||
typedef std::map<ULONG, ULONG> Base;
|
||
DiaRegToRegRelativeI386();
|
||
} g_DiaRegToRegRelativeI386;
|
||
|
||
DiaRegToRegRelativeI386::DiaRegToRegRelativeI386()
|
||
{
|
||
(*this)[CV_REG_EIP] = rriInstructionPointer;
|
||
(*this)[CV_REG_EBP] = rriStackFrame;
|
||
(*this)[CV_REG_ESP] = rriStackPointer;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
|
||
const std::string DiaException::descPrefix("pyDia: ");
|
||
|
||
std::string DiaException::makeFullDesc(const std::string &desc, HRESULT hres, IDiaSymbol *symbol /*= NULL*/)
|
||
{
|
||
std::stringstream sstream;
|
||
sstream << descPrefix << desc << " failed" << std::endl;
|
||
if (symbol)
|
||
{
|
||
BSTR bstrName = NULL;
|
||
HRESULT locRes = symbol->get_undecoratedName(&bstrName);
|
||
if (S_OK == locRes && bstrName)
|
||
{
|
||
autoBstr freeBstr(bstrName);
|
||
sstream << "Symbol name: \"" << autoBstr::asStr(bstrName) << "\"";
|
||
}
|
||
else
|
||
{
|
||
locRes = symbol->get_name(&bstrName);
|
||
if (S_OK == locRes && bstrName)
|
||
{
|
||
autoBstr freeBstr(bstrName);
|
||
sstream << "Symbol name: " << autoBstr::asStr(bstrName);
|
||
}
|
||
else
|
||
{
|
||
sstream << "Symbol: ";
|
||
}
|
||
}
|
||
|
||
DWORD dwValue;
|
||
locRes = symbol->get_relativeVirtualAddress(&dwValue);
|
||
if (S_OK == locRes)
|
||
{
|
||
sstream << ", RVA= 0x" << std::hex << dwValue;
|
||
}
|
||
|
||
locRes = symbol->get_symTag(&dwValue);
|
||
if (S_OK == locRes)
|
||
{
|
||
sstream << ", tag= " << std::dec << dwValue;
|
||
}
|
||
|
||
locRes = symbol->get_locationType(&dwValue);
|
||
if (S_OK == locRes)
|
||
{
|
||
sstream << ", location: " << std::dec << dwValue;
|
||
}
|
||
|
||
sstream << std::endl;
|
||
}
|
||
sstream << "Return value is 0x" << std::hex << hres;
|
||
|
||
switch (hres)
|
||
{
|
||
#define _CASE_DIA_ERROR(x) case E_PDB_##x: sstream << ": E_PDB_" #x << std::endl; break
|
||
|
||
_CASE_DIA_ERROR(USAGE);
|
||
_CASE_DIA_ERROR(OUT_OF_MEMORY);
|
||
_CASE_DIA_ERROR(FILE_SYSTEM);
|
||
_CASE_DIA_ERROR(NOT_FOUND);
|
||
_CASE_DIA_ERROR(INVALID_SIG);
|
||
_CASE_DIA_ERROR(INVALID_AGE);
|
||
_CASE_DIA_ERROR(PRECOMP_REQUIRED);
|
||
_CASE_DIA_ERROR(OUT_OF_TI);
|
||
_CASE_DIA_ERROR(NOT_IMPLEMENTED);
|
||
_CASE_DIA_ERROR(V1_PDB);
|
||
_CASE_DIA_ERROR(FORMAT);
|
||
_CASE_DIA_ERROR(LIMIT);
|
||
_CASE_DIA_ERROR(CORRUPT);
|
||
_CASE_DIA_ERROR(TI16);
|
||
_CASE_DIA_ERROR(ACCESS_DENIED);
|
||
_CASE_DIA_ERROR(ILLEGAL_TYPE_EDIT);
|
||
_CASE_DIA_ERROR(INVALID_EXECUTABLE);
|
||
_CASE_DIA_ERROR(DBG_NOT_FOUND);
|
||
_CASE_DIA_ERROR(NO_DEBUG_INFO);
|
||
_CASE_DIA_ERROR(INVALID_EXE_TIMESTAMP);
|
||
_CASE_DIA_ERROR(RESERVED);
|
||
_CASE_DIA_ERROR(DEBUG_INFO_NOT_IN_PDB);
|
||
_CASE_DIA_ERROR(SYMSRV_BAD_CACHE_PATH);
|
||
_CASE_DIA_ERROR(SYMSRV_CACHE_FULL);
|
||
|
||
#undef _CASE_DIA_ERROR
|
||
default:
|
||
{
|
||
PCHAR errMessage = NULL;
|
||
FormatMessageA(
|
||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||
NULL,
|
||
hres,
|
||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||
(PCHAR)&errMessage,
|
||
0,
|
||
NULL);
|
||
if (errMessage)
|
||
{
|
||
sstream << ": " << std::endl;
|
||
sstream << errMessage;
|
||
LocalFree(errMessage);
|
||
}
|
||
else
|
||
{
|
||
sstream << std::endl;
|
||
}
|
||
}
|
||
}
|
||
|
||
return sstream.str();
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
#define callSymbol(method) \
|
||
callSymbolT( &IDiaSymbol::##method, #method)
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////
|
||
|
||
std::string getBasicTypeName( ULONG basicType )
|
||
{
|
||
for ( size_t i = 0; i < DiaSymbol::cntBasicTypeName; ++i )
|
||
{
|
||
if ( basicType == DiaSymbol::basicTypeName[i].first )
|
||
return std::string( DiaSymbol::basicTypeName[i].second );
|
||
}
|
||
|
||
std::stringstream sstr;
|
||
|
||
sstr << "faild to find basic type with index %d" << basicType;
|
||
|
||
throw DiaException( sstr.str() );
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
DiaSymbol::DiaSymbol(__inout DiaSymbolPtr &_symbol, DWORD machineType )
|
||
: m_symbol(_symbol), m_machineType(machineType)
|
||
{
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////
|
||
|
||
SymbolPtr DiaSymbol::fromGlobalScope( IDiaSymbol *_symbol )
|
||
{
|
||
DWORD machineType;
|
||
HRESULT hres = _symbol->get_machineType(&machineType);
|
||
if (S_OK != hres)
|
||
throw DiaException("IDiaSymbol::get_machineType", hres);
|
||
if (!machineType)
|
||
machineType = IMAGE_FILE_MACHINE_I386;
|
||
|
||
return SymbolPtr( new DiaSymbol(DiaSymbolPtr(_symbol), machineType) );
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////
|
||
|
||
SymbolPtrList DiaSymbol::findChildren(
|
||
ULONG symTag,
|
||
const std::string &name,
|
||
bool caseSensitive
|
||
)
|
||
{
|
||
DiaEnumSymbolsPtr symbols;
|
||
HRESULT hres;
|
||
|
||
if ( name.empty() )
|
||
{
|
||
hres = m_symbol->findChildren(
|
||
static_cast<enum ::SymTagEnum>(symTag),
|
||
NULL,
|
||
(caseSensitive ? nsCaseSensitive : nsCaseInsensitive) | nsfUndecoratedName | nsfRegularExpression,
|
||
&symbols);
|
||
|
||
}
|
||
else
|
||
{
|
||
hres = m_symbol->findChildren(
|
||
static_cast<enum ::SymTagEnum>(symTag),
|
||
toWStr(name),
|
||
(caseSensitive ? nsCaseSensitive : nsCaseInsensitive) | nsfUndecoratedName | nsfRegularExpression,
|
||
&symbols);
|
||
}
|
||
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaSymbol::findChildren", hres);
|
||
|
||
SymbolPtrList childList;
|
||
|
||
DiaSymbolPtr child;
|
||
ULONG celt;
|
||
while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
|
||
{
|
||
childList.push_back( SymbolPtr( new DiaSymbol(child, m_machineType) ) );
|
||
child = NULL;
|
||
}
|
||
|
||
return childList;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getBaseType()
|
||
{
|
||
return callSymbol(get_baseType);
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getBitPosition()
|
||
{
|
||
return callSymbol(get_bitPosition);
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getChildCount(ULONG symTag)
|
||
{
|
||
DiaEnumSymbolsPtr symbols;
|
||
HRESULT hres =
|
||
m_symbol->findChildren(
|
||
static_cast<enum ::SymTagEnum>(symTag),
|
||
NULL,
|
||
nsfCaseSensitive | nsfUndecoratedName,
|
||
&symbols);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaSymbol::findChildren", hres);
|
||
|
||
LONG count;
|
||
hres = symbols->get_Count(&count);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaEnumSymbols::get_Count", hres);
|
||
|
||
return count;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
SymbolPtr DiaSymbol::getChildByIndex(ULONG symTag, ULONG _index )
|
||
{
|
||
DiaEnumSymbolsPtr symbols;
|
||
HRESULT hres =
|
||
m_symbol->findChildren(
|
||
static_cast<enum ::SymTagEnum>(symTag),
|
||
NULL,
|
||
nsfCaseSensitive | nsfUndecoratedName,
|
||
&symbols);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaSymbol::findChildren", hres);
|
||
|
||
LONG count;
|
||
hres = symbols->get_Count(&count);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaEnumSymbols::get_Count", hres);
|
||
|
||
if (LONG(_index) >= count)
|
||
{
|
||
throw PyException( PyExc_IndexError, "Index out of range");
|
||
}
|
||
|
||
DiaSymbolPtr child;
|
||
hres = symbols->Item(_index, &child);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaEnumSymbols::Item", hres);
|
||
|
||
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
SymbolPtr DiaSymbol::getChildByName(const std::string &name )
|
||
{
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
DiaEnumSymbolsPtr symbols;
|
||
HRESULT hres =
|
||
m_symbol->findChildren(
|
||
::SymTagNull,
|
||
toWStr(name),
|
||
nsfCaseSensitive | nsfUndecoratedName,
|
||
&symbols);
|
||
|
||
LONG count;
|
||
hres = symbols->get_Count(&count);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaEnumSymbols::get_Count", hres);
|
||
|
||
if (count >0 )
|
||
{
|
||
DiaSymbolPtr child;
|
||
hres = symbols->Item(0, &child);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaEnumSymbols::Item", hres);
|
||
|
||
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
||
}
|
||
|
||
// _<><5F><EFBFBD>
|
||
std::string underscoreName;
|
||
underscoreName += '_';
|
||
underscoreName += name;
|
||
symbols = 0;
|
||
|
||
hres =
|
||
m_symbol->findChildren(
|
||
::SymTagNull,
|
||
toWStr(underscoreName),
|
||
nsfCaseSensitive | nsfUndecoratedName,
|
||
&symbols);
|
||
|
||
hres = symbols->get_Count(&count);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaEnumSymbols::get_Count", hres);
|
||
|
||
if (count >0 )
|
||
{
|
||
DiaSymbolPtr child;
|
||
hres = symbols->Item(0, &child);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaEnumSymbols::Item", hres);
|
||
|
||
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
||
}
|
||
|
||
// _<><5F><EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD>
|
||
std::string pattern = "_";
|
||
pattern += name;
|
||
pattern += "@*";
|
||
symbols = 0;
|
||
|
||
hres =
|
||
m_symbol->findChildren(
|
||
::SymTagNull,
|
||
toWStr(pattern),
|
||
nsfRegularExpression | nsfCaseSensitive | nsfUndecoratedName,
|
||
&symbols);
|
||
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaSymbol::findChildren", hres);
|
||
|
||
hres = symbols->get_Count(&count);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaEnumSymbols::get_Count", hres);
|
||
|
||
if (count == 0)
|
||
throw DiaException( name + " not found");
|
||
|
||
if (count >0 )
|
||
{
|
||
DiaSymbolPtr child;
|
||
hres = symbols->Item(0, &child);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaEnumSymbols::Item", hres);
|
||
|
||
return SymbolPtr( new DiaSymbol(child, m_machineType) );
|
||
}
|
||
|
||
throw DiaException(name + " is not found");
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getCount()
|
||
{
|
||
return callSymbol(get_count);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getDataKind()
|
||
{
|
||
return callSymbol(get_dataKind);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getRegRealativeId()
|
||
{
|
||
switch (m_machineType)
|
||
{
|
||
case IMAGE_FILE_MACHINE_AMD64:
|
||
return getRegRealativeIdImpl(g_DiaRegToRegRelativeAmd64);
|
||
case IMAGE_FILE_MACHINE_I386:
|
||
return getRegRealativeIdImpl(g_DiaRegToRegRelativeI386);
|
||
}
|
||
throw DiaException("Unsupported machine type");
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getRegRealativeIdImpl(const DiaRegToRegRelativeBase &DiaRegToRegRelative)
|
||
{
|
||
DiaRegToRegRelativeBase::const_iterator it =
|
||
DiaRegToRegRelative.find(callSymbol(get_registerId));
|
||
|
||
if (it == DiaRegToRegRelative.end())
|
||
throw DiaException("Cannot convert DAI register ID to relative register ID");
|
||
|
||
return it->second;
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getIndexId()
|
||
{
|
||
return callSymbol(get_symIndexId);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
SymbolPtr DiaSymbol::getIndexType()
|
||
{
|
||
DiaSymbolPtr diaSymbol(callSymbol(get_arrayIndexType));
|
||
return SymbolPtr( new DiaSymbol(diaSymbol, m_machineType) );
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getLocType()
|
||
{
|
||
return callSymbol(get_locationType);
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
static const boost::regex stdcallMatch("^_(\\w+)(@\\d+)?$");
|
||
static const boost::regex fastcallMatch("^@(\\w+)(@\\d+)?$");
|
||
|
||
std::string DiaSymbol::getName()
|
||
{
|
||
HRESULT hres;
|
||
BSTR bstrName = NULL;
|
||
|
||
ULONG symTag;
|
||
hres = m_symbol->get_symTag( &symTag );
|
||
|
||
if ( FAILED( hres ) )
|
||
throw DiaException("Call IDiaSymbol::get_symTag", hres);
|
||
|
||
if( symTag == SymTagData || symTag == SymTagFunction || symTag == SymTagPublicSymbol )
|
||
{
|
||
hres = m_symbol->get_undecoratedNameEx( UNDNAME_NAME_ONLY, &bstrName);
|
||
if ( FAILED( hres ) )
|
||
throw DiaException("Call IDiaSymbol::get_undecoratedNameEx", hres);
|
||
|
||
std::string retStr = autoBstr( bstrName ).asStr();
|
||
|
||
if ( !retStr.empty() )
|
||
{
|
||
boost::cmatch matchResult;
|
||
|
||
if ( boost::regex_match( retStr.c_str(), matchResult, stdcallMatch ) )
|
||
return std::string( matchResult[1].first, matchResult[1].second );
|
||
|
||
if ( boost::regex_match( retStr.c_str(), matchResult, fastcallMatch ) )
|
||
return std::string( matchResult[1].first, matchResult[1].second );
|
||
|
||
return retStr;
|
||
}
|
||
}
|
||
|
||
bstrName = callSymbol(get_name);
|
||
|
||
return autoBstr( bstrName ).asStr();
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
|
||
LONG DiaSymbol::getOffset()
|
||
{
|
||
return callSymbol(get_offset);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getRva()
|
||
{
|
||
return callSymbol(get_relativeVirtualAddress);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONGLONG DiaSymbol::getSize()
|
||
{
|
||
return callSymbol(get_length);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getSymTag()
|
||
{
|
||
return callSymbol(get_symTag);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
SymbolPtr DiaSymbol::getType()
|
||
{
|
||
DiaSymbolPtr diaSymbol(callSymbol(get_type));
|
||
return SymbolPtr( new DiaSymbol( diaSymbol, m_machineType ) );
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getUdtKind()
|
||
{
|
||
return callSymbol(get_udtKind);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONGLONG DiaSymbol::getVa()
|
||
{
|
||
return callSymbol(get_virtualAddress);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
void DiaSymbol::getValue( BaseTypeVariant &btv )
|
||
{
|
||
CComVariant vtValue;
|
||
HRESULT hres = m_symbol->get_value(&vtValue);
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaSymbol::get_value", hres);
|
||
|
||
switch (vtValue.vt)
|
||
{
|
||
case VT_I1:
|
||
btv = (LONG)vtValue.bVal;
|
||
break;
|
||
|
||
case VT_UI1:
|
||
btv = (ULONG)vtValue.bVal;
|
||
break;
|
||
|
||
case VT_BOOL:
|
||
btv = !!vtValue.iVal;
|
||
break;
|
||
|
||
case VT_I2:
|
||
btv = (LONG)vtValue.iVal;
|
||
break;
|
||
|
||
case VT_UI2:
|
||
btv = (ULONG)vtValue.iVal;
|
||
break;
|
||
|
||
case VT_I4:
|
||
case VT_INT:
|
||
btv = (LONG)vtValue.lVal;
|
||
break;
|
||
|
||
case VT_UI4:
|
||
case VT_UINT:
|
||
case VT_ERROR:
|
||
case VT_HRESULT:
|
||
btv = (ULONG)vtValue.lVal;
|
||
break;
|
||
|
||
case VT_I8:
|
||
btv = (ULONG64)vtValue.llVal;
|
||
break;
|
||
|
||
case VT_UI8:
|
||
btv = (LONG64)vtValue.llVal;
|
||
break;
|
||
|
||
//case VT_R4:
|
||
// btv = vtValue.fltVal;
|
||
// break;
|
||
|
||
//case VT_R8:
|
||
// fillDataBuff(vtValue.dblVal);
|
||
// break;
|
||
|
||
default:
|
||
throw DbgException( "Unsupported const value" );
|
||
}
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
int DiaSymbol::getVirtualBasePointerOffset()
|
||
{
|
||
return callSymbol(get_virtualBasePointerOffset);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getVirtualBaseDispIndex()
|
||
{
|
||
return callSymbol(get_virtualBaseDispIndex);
|
||
}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
|
||
ULONG DiaSymbol::getVirtualBaseDispSize()
|
||
{
|
||
DiaSymbolPtr diaSymbol(callSymbol(get_virtualBaseTableType));
|
||
SymbolPtr baseTableType = SymbolPtr( new DiaSymbol( diaSymbol, m_machineType ) );
|
||
|
||
return (ULONG)baseTableType->getType()->getSize();
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
bool DiaSymbol::isBasicType()
|
||
{
|
||
DWORD baseType = btNoType;
|
||
return
|
||
SUCCEEDED( m_symbol->get_baseType(&baseType) ) &&
|
||
(btNoType != baseType);
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
bool DiaSymbol::isConstant()
|
||
{
|
||
HRESULT hres;
|
||
BOOL retBool = FALSE;
|
||
|
||
hres = m_symbol->get_constType( &retBool );
|
||
if ( FAILED( hres ) )
|
||
throw DiaException("Call IDiaSymbol::get_constType", hres, m_symbol);
|
||
|
||
return !!retBool;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
bool DiaSymbol::isIndirectVirtualBaseClass()
|
||
{
|
||
return !!callSymbol(get_indirectVirtualBaseClass);
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
bool DiaSymbol::isVirtualBaseClass()
|
||
{
|
||
return !!callSymbol(get_virtualBaseClass);
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
SymbolPtr DiaSession::findByRva( ULONG rva, ULONG symTag, LONG* pdisplacement )
|
||
{
|
||
DiaSymbolPtr child;
|
||
LONG displacement;
|
||
|
||
HRESULT hres =
|
||
m_session->findSymbolByRVAEx(
|
||
rva,
|
||
static_cast<enum ::SymTagEnum>(symTag),
|
||
&child,
|
||
&displacement);
|
||
|
||
if (S_OK != hres)
|
||
throw DiaException("Call IDiaSession::findSymbolByRVAEx", hres);
|
||
if (!child)
|
||
throw DiaException("Call IDiaSession::findSymbolByRVAEx", E_UNEXPECTED);
|
||
if ( !pdisplacement && displacement)
|
||
throw DiaException("Call IDiaSession::findSymbolByRVAEx failed to find suymbol" );
|
||
|
||
if (pdisplacement)
|
||
*pdisplacement = displacement;
|
||
|
||
return SymbolPtr( new DiaSymbol(child, m_globalSymbol->getMachineType() ) );
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
|
||
void DiaSession::getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement )
|
||
{
|
||
DiaEnumLineNumbersPtr lines;
|
||
|
||
HRESULT hres = m_session->findLinesByVA( offset, 1, &lines );
|
||
if (S_OK != hres)
|
||
throw DiaException("failed to find source line");
|
||
|
||
DiaLineNumberPtr sourceLine;
|
||
hres = lines->Item( 0, &sourceLine );
|
||
if (S_OK != hres)
|
||
throw DiaException("failed to find source line");
|
||
|
||
DiaSourceFilePtr sourceFile;
|
||
hres = sourceLine->get_sourceFile( &sourceFile );
|
||
if (S_OK != hres)
|
||
throw DiaException("failed to find source line");
|
||
|
||
autoBstr fileNameBstr;
|
||
hres = sourceFile->get_fileName ( &fileNameBstr );
|
||
if (S_OK != hres)
|
||
throw DiaException("failed to find source line");
|
||
fileName = fileNameBstr.asStr();
|
||
|
||
hres = sourceLine->get_lineNumber( &lineNo );
|
||
if (S_OK != hres)
|
||
throw DiaException("failed to find source line");
|
||
|
||
ULONGLONG va;
|
||
hres = sourceLine->get_virtualAddress ( &va );
|
||
if (S_OK != hres)
|
||
throw DiaException("failed to find source line");
|
||
|
||
displacement = (LONG)( (LONGLONG)offset - (LONGLONG)va );
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
|
||
}; // pykd nemaspace end
|
||
|