mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 19:53:22 +08:00
253 lines
6.1 KiB
C++
253 lines
6.1 KiB
C++
|
|
#pragma once
|
|
|
|
#include "symengine.h"
|
|
#include "dbgexcept.h"
|
|
|
|
#include <dia2.h>
|
|
|
|
namespace pykd {
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef CComPtr< IDiaSymbol > DiaSymbolPtr;
|
|
typedef CComPtr< IDiaEnumSymbols > DiaEnumSymbolsPtr;
|
|
typedef CComPtr< IDiaDataSource > DiaDataSourcePtr;
|
|
typedef CComPtr< IDiaSession > DiaSessionPtr;
|
|
typedef CComPtr< IDiaEnumSymbolsByAddr > DiaEnumSymbolsByAddrPtr;
|
|
typedef CComPtr< IDiaEnumLineNumbers > DiaEnumLineNumbersPtr;
|
|
typedef CComPtr< IDiaLineNumber> DiaLineNumberPtr;
|
|
typedef CComPtr< IDiaSourceFile > DiaSourceFilePtr;
|
|
|
|
typedef std::map<ULONG, ULONG> DiaRegToRegRelativeBase;
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
class DiaException : public SymbolException {
|
|
public:
|
|
DiaException(const std::string &desc, HRESULT hres, IDiaSymbol *symbol = NULL)
|
|
: SymbolException( makeFullDesc(desc, hres, symbol) )
|
|
, m_hres(hres)
|
|
{
|
|
}
|
|
|
|
DiaException(const std::string &desc)
|
|
: SymbolException(descPrefix + desc)
|
|
, m_hres(S_FALSE)
|
|
{
|
|
}
|
|
|
|
HRESULT getRes() const {
|
|
return m_hres;
|
|
}
|
|
private:
|
|
|
|
static const std::string descPrefix;
|
|
|
|
static std::string makeFullDesc(const std::string &desc, HRESULT hres, IDiaSymbol *symbol = NULL);
|
|
|
|
HRESULT m_hres;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
class DiaSymbol : public Symbol {
|
|
public:
|
|
DiaSymbol( DiaSymbolPtr &_symbol, DWORD machineType );
|
|
|
|
static SymbolPtr fromGlobalScope( IDiaSymbol *_symbol );
|
|
|
|
SymbolPtr getChildByName(const std::string &_name );
|
|
|
|
ULONG getRva();
|
|
|
|
SymbolPtrList findChildren(
|
|
ULONG symTag,
|
|
const std::string &name = "",
|
|
bool caseSensitive = FALSE
|
|
);
|
|
|
|
ULONGLONG getSize();
|
|
|
|
std::string getName();
|
|
|
|
SymbolPtr getType();
|
|
|
|
SymbolPtr getIndexType();
|
|
|
|
ULONG getSymTag();
|
|
|
|
ULONGLONG getVa();
|
|
|
|
ULONG getLocType();
|
|
|
|
LONG getOffset();
|
|
|
|
ULONG getCount();
|
|
|
|
void getValue( BaseTypeVariant &vtValue );
|
|
|
|
bool isBasicType();
|
|
|
|
bool isIndirectVirtualBaseClass();
|
|
|
|
bool isVirtualBaseClass();
|
|
|
|
ULONG getBaseType();
|
|
|
|
ULONG getBitPosition();
|
|
|
|
ULONG getIndexId();
|
|
|
|
ULONG getUdtKind();
|
|
|
|
ULONG getDataKind();
|
|
|
|
//ULONG getRegisterId();
|
|
virtual ULONG getRegRealativeId() override;
|
|
|
|
ULONG getMachineType() {
|
|
return m_machineType;
|
|
}
|
|
|
|
//SymbolPtr getChildByName(const std::string &_name);
|
|
|
|
ULONG getChildCount( ULONG symTag );
|
|
|
|
ULONG getChildCount() {
|
|
return getChildCount(SymTagNull);
|
|
}
|
|
|
|
SymbolPtr getChildByIndex(ULONG symTag, ULONG _index );
|
|
|
|
SymbolPtr getChildByIndex(ULONG _index ) {
|
|
return getChildByIndex( SymTagNull, _index );
|
|
}
|
|
|
|
bool isConstant();
|
|
|
|
//std::string print();
|
|
|
|
//bool eq(Symbol &rhs);
|
|
|
|
int getVirtualBasePointerOffset();
|
|
|
|
ULONG getVirtualBaseDispIndex();
|
|
|
|
ULONG getVirtualBaseDispSize();
|
|
|
|
//ULONG getSection();
|
|
|
|
void setLoadAddress( ULONGLONG baseAddress );
|
|
|
|
public:
|
|
typedef std::pair<ULONG, const char *> ValueNameEntry;
|
|
|
|
//static const ValueNameEntry dataKindName[DataIsConstant + 1];
|
|
|
|
//static const ValueNameEntry symTagName[SymTagMax];
|
|
|
|
//static const ValueNameEntry locTypeName[LocTypeMax];
|
|
|
|
static const ValueNameEntry basicTypeName[];
|
|
static const size_t cntBasicTypeName;
|
|
|
|
//static const ValueNameEntry udtKindName[];
|
|
//static const size_t cntUdtKindName;
|
|
|
|
//static const ValueNameEntry i386RegName[];
|
|
//static const size_t cntI386RegName;
|
|
|
|
//static const ValueNameEntry amd64RegName[];
|
|
//static const size_t cntAmd64RegName;
|
|
|
|
static std::string getBasicTypeName( ULONG basicType );
|
|
|
|
protected:
|
|
|
|
//// Check symbols loop
|
|
//class checkSymLoop
|
|
//{
|
|
//public:
|
|
// checkSymLoop(checkSymLoop *prev)
|
|
// : m_symSetPtr( prev ? prev->m_symSetPtr : symSetPtr(new symSet) )
|
|
// {
|
|
// }
|
|
|
|
// bool check(IDiaSymbol *_symbol)
|
|
// {
|
|
// DWORD symIndexId = 0;
|
|
// _symbol->get_symIndexId(&symIndexId);
|
|
// return !m_symSetPtr->insert(symIndexId).second;
|
|
// }
|
|
|
|
//private:
|
|
// typedef std::set<DWORD> symSet;
|
|
// typedef boost::shared_ptr<symSet> symSetPtr;
|
|
// symSetPtr m_symSetPtr;
|
|
//};
|
|
|
|
//static std::string printImpl(
|
|
// IDiaSymbol *_symbol,
|
|
// DWORD machineType,
|
|
// ULONG indent = 0,
|
|
// checkSymLoop *checkLoopPrev = NULL,
|
|
// const char *prefix = NULL
|
|
//);
|
|
|
|
ULONG getRegRealativeIdImpl(const DiaRegToRegRelativeBase &DiaRegToRegRelative);
|
|
|
|
template <typename TRet>
|
|
TRet callSymbolT(
|
|
HRESULT(STDMETHODCALLTYPE IDiaSymbol::*method)(TRet *),
|
|
const char *methodName
|
|
)
|
|
{
|
|
TRet retValue;
|
|
HRESULT hres = (m_symbol->*method)(&retValue);
|
|
if (S_OK != hres)
|
|
throw DiaException(std::string("Call IDiaSymbol::") + methodName, hres, m_symbol);
|
|
|
|
return retValue;
|
|
}
|
|
|
|
DiaSymbolPtr m_symbol;
|
|
|
|
DWORD m_machineType;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
class DiaSession : public SymbolSession
|
|
{
|
|
public:
|
|
|
|
DiaSession( IDiaSession* session, IDiaSymbol *globalScope ) :
|
|
m_globalScope( globalScope ),
|
|
m_globalSymbol( DiaSymbol::fromGlobalScope( globalScope ) ),
|
|
m_session( session )
|
|
{}
|
|
|
|
SymbolPtr& getSymbolScope() {
|
|
return m_globalSymbol;
|
|
}
|
|
|
|
SymbolPtr findByRva( ULONG rva, ULONG symTag = SymTagNull, LONG* displacement = NULL );
|
|
|
|
ULONG findRvaByName( const std::string &name );
|
|
|
|
void getSourceLine( ULONG64 offset, std::string &fileName, ULONG &lineNo, LONG &displacement );
|
|
|
|
private:
|
|
|
|
DiaSymbolPtr m_globalScope;
|
|
SymbolPtr m_globalSymbol;
|
|
DiaSessionPtr m_session;
|
|
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
} // end pykd namespace
|
|
|