diawrapper.h 6.25 KB
Newer Older
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#pragma once

#include <map>

#include <dia2.h>
#include <atlbase.h>

#include "kdlib/symengine.h"
#include "kdlib/exceptions.h"

namespace kdlib {

//////////////////////////////////////////////////////////////////////////////

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::wstring &desc, HRESULT hres, IDiaSymbol *symbol = NULL)
        : SymbolException( makeFullDesc(desc, hres, symbol) )
        , m_hres(hres)
    {
    }

    DiaException(const std::wstring &desc)
        : SymbolException(descPrefix + desc)
        , m_hres(S_FALSE)
    {
    }

    HRESULT getRes() const {
        return m_hres;
    }
private:

    static const std::wstring descPrefix;

    static std::wstring makeFullDesc(const std::wstring &desc, HRESULT hres, IDiaSymbol *symbol = NULL);

    HRESULT m_hres;
};

////////////////////////////////////////////////////////////////////////////

class DiaSymbol : public Symbol {
public:
ussrhero's avatar
ussrhero committed
58
    DiaSymbol(const  DiaSymbolPtr &_symbol, const std::wstring &_scope, MachineTypes machineType );
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
59

60
    static SymbolPtr fromGlobalScope( IDiaSymbol *_symbol, const std::wstring &_scope );
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
61

ussrhero's avatar
ussrhero committed
62
    SymbolPtr getChildByName(const std::wstring &_name ) override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
63

ussrhero's avatar
ussrhero committed
64 65
    ULONG getRva() override;
     
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
66 67 68 69
    SymbolPtrList findChildren(
        ULONG symTag,
        const std::wstring &name = L"",
        bool caseSensitive = FALSE
ussrhero's avatar
ussrhero committed
70
    ) override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
71

ussrhero's avatar
ussrhero committed
72
    SymbolPtrList findChildrenByRVA(unsigned long symTag, unsigned long rva) override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
73

ussrhero's avatar
ussrhero committed
74
    size_t getSize() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
75

ussrhero's avatar
ussrhero committed
76 77
    std::wstring getName() override;
    std::wstring getScopeName() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
78

ussrhero's avatar
ussrhero committed
79
    SymbolPtr getType() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
80

ussrhero's avatar
ussrhero committed
81
    SymbolPtr getIndexType() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
82

ussrhero's avatar
ussrhero committed
83
    SymTags getSymTag() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
84

ussrhero's avatar
ussrhero committed
85
    ULONGLONG getVa() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
86

ussrhero's avatar
ussrhero committed
87
    ULONG getLocType() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
88

ussrhero's avatar
ussrhero committed
89
    LONG getOffset() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
90

ussrhero's avatar
ussrhero committed
91
    size_t getCount() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
92

ussrhero's avatar
ussrhero committed
93
    void getValue( NumVariant &vtValue ) override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
94

ussrhero's avatar
ussrhero committed
95
    bool isBasicType() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
96

ussrhero's avatar
ussrhero committed
97
    bool isIndirectVirtualBaseClass() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
98

ussrhero's avatar
ussrhero committed
99
    bool isVirtualBaseClass() override;
SND\ussrhero_cp's avatar
 
SND\ussrhero_cp committed
100

ussrhero's avatar
ussrhero committed
101
    bool isVirtual() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
102

ussrhero's avatar
ussrhero committed
103
    ULONG getBaseType() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
104

ussrhero's avatar
ussrhero committed
105
    ULONG getBitPosition() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
106

ussrhero's avatar
ussrhero committed
107
    ULONG getUdtKind() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
108

ussrhero's avatar
ussrhero committed
109
    ULONG getDataKind() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
110

ussrhero's avatar
ussrhero committed
111
    ULONG getRegisterId() override;
112

ussrhero's avatar
ussrhero committed
113
    unsigned long getRegRealativeId() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
114

ussrhero's avatar
ussrhero committed
115
    SymbolPtr getObjectPointerType() override;
116

ussrhero's avatar
ussrhero committed
117
    ULONG getCallingConvention() override;
118

ussrhero's avatar
ussrhero committed
119
    SymbolPtr getClassParent() override;
120

ussrhero's avatar
ussrhero committed
121
    MachineTypes getMachineType() override {
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
122 123 124
        return m_machineType;
    }

ussrhero's avatar
ussrhero committed
125
    size_t getChildCount( ULONG symTag ) override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
126

ussrhero's avatar
ussrhero committed
127 128
    size_t getChildCount() override
    {
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
129 130 131
        return getChildCount(SymTagNull);
    }

ussrhero's avatar
ussrhero committed
132
    SymbolPtr getChildByIndex(ULONG symTag, ULONG _index ) override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
133

ussrhero's avatar
ussrhero committed
134 135
    SymbolPtr getChildByIndex(ULONG _index ) override
    {
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
136 137 138
        return getChildByIndex( SymTagNull, _index );
    }
    
ussrhero's avatar
ussrhero committed
139 140 141
    bool isConstant() override;

    int getVirtualBasePointerOffset() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
142

ussrhero's avatar
ussrhero committed
143
    ULONG getVirtualBaseDispIndex() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
144

ussrhero's avatar
ussrhero committed
145
    ULONG getVirtualBaseDispSize() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
146

ussrhero's avatar
ussrhero committed
147
    SymbolPtr getVirtualTableShape() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
148

ussrhero's avatar
ussrhero committed
149
    unsigned long getVirtualBaseOffset() override;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
150

ussrhero's avatar
ussrhero committed
151
    SymbolPtrList findInlineFramesByVA(MEMOFFSET_64 va) override;
SND\ussrhero_cp's avatar
 
SND\ussrhero_cp committed
152

ussrhero's avatar
ussrhero committed
153
    void getInlineSourceLine(MEMOFFSET_64, std::wstring &fileName, unsigned long &lineNo) override;
SND\ussrhero_cp's avatar
 
SND\ussrhero_cp committed
154

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
155 156 157 158 159
public:
    typedef std::pair<ULONG, const wchar_t *> ValueNameEntry;
    static const ValueNameEntry basicTypeName[];
    static const size_t cntBasicTypeName;

ussrhero's avatar
ussrhero committed
160
    //static std::string getBasicTypeName( ULONG basicType );
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
161 162 163 164 165

protected:

    ULONG getRegRealativeIdImpl(const DiaRegToRegRelativeBase &DiaRegToRegRelative);

166
    bool isUndecorated(const std::wstring &undecName);
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
167 168 169 170 171 172 173 174 175 176 177
    
    template<typename TRet>
    struct ReturnType {
        typedef TRet type;
    };

    template <>
    struct ReturnType<IDiaSymbol*>{
        typedef CComPtr<IDiaSymbol> type;
    };

178

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
179
    template <typename TRet>
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
180
    typename ReturnType<TRet>::type callSymbolT(
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
181 182
        HRESULT(STDMETHODCALLTYPE IDiaSymbol::*method)(TRet *),
        const wchar_t *methodName
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
183
     )
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
184
    {
SND\ussrhero_cp's avatar
SND\ussrhero_cp committed
185
        ReturnType<TRet>::type retValue;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
186 187 188 189 190 191 192
        HRESULT hres = (m_symbol->*method)(&retValue);
        if (S_OK != hres)
            throw DiaException(std::wstring(L"Call IDiaSymbol::") + methodName, hres, m_symbol);
        return retValue;
    }

    DiaSymbolPtr m_symbol;
193
    std::wstring m_scope;
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
194 195 196 197 198 199 200 201 202 203 204 205

    MachineTypes m_machineType;
};

////////////////////////////////////////////////////////////////////////////

class DiaSession : public SymbolSession
{
public:

    DiaSession( IDiaSession* session, IDiaSymbol *globalScope, const std::wstring symbolFile ) :
        m_globalScope( globalScope ),
206
        m_globalSymbol( DiaSymbol::fromGlobalScope( globalScope, getScopeName( session, globalScope ) ) ),
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
207 208
        m_session( session ),
        m_symbolFileName( symbolFile )
209
        {}
SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224

    virtual SymbolPtr getSymbolScope() {
        return m_globalSymbol;
    }

    virtual SymbolPtr findByRva( ULONG rva, ULONG symTag = SymTagNull, LONG* displacement = NULL );

    virtual void getSourceLine( ULONG64 offset, std::wstring &fileName, ULONG &lineNo, LONG &displacement );

    virtual std::wstring getSymbolFileName() {
        return m_symbolFileName;
    }

private:

225
    static std::wstring getScopeName( IDiaSession* session, IDiaSymbol *globalScope );
226

SND\kernelnet_cp's avatar
SND\kernelnet_cp committed
227 228 229 230 231 232 233 234 235 236 237 238 239
    ULONG findRvaByName( const std::string &name );

    DiaSymbolPtr    m_globalScope;
    SymbolPtr       m_globalSymbol;
    DiaSessionPtr   m_session;
    std::wstring     m_symbolFileName;

};

////////////////////////////////////////////////////////////////////////////

} // end kdlib namespace