kdlibcpp

Форк
0
/
diawrapper.cpp 
928 строк · 26.5 Кб
1

2
#include "stdafx.h"
3

4
#include <comutil.h>
5

6
#include <dbghelp.h>
7
#pragma comment(lib, "dbghelp.lib")
8

9
#include <boost/regex.hpp>
10

11
#include "kdlib/symengine.h"
12
#include "dia/diawrapper.h"
13
#include "win/utils.h"
14

15
namespace kdlib {
16

17
///////////////////////////////////////////////////////////////////////////////
18

19
namespace {
20

21
const DiaRegToRegRelativeBase g_DiaRegToRegRelativeAmd64 {
22
    { CV_AMD64_RIP, rriInstructionPointer },
23
    { CV_AMD64_RBP, rriStackFrame },
24
    { CV_ALLREG_VFRAME, rriStackFrame },
25
    { CV_AMD64_RSP, rriStackPointer },
26
};
27

28
const DiaRegToRegRelativeBase g_DiaRegToRegRelativeI386 {
29
    { CV_REG_EIP,       rriInstructionPointer },
30
    { CV_REG_EBP,       rriStackFrame },
31
    { CV_ALLREG_VFRAME, rriStackFrame },
32
    { CV_REG_ESP,       rriStackPointer },
33
};
34

35
const DiaRegToRegRelativeBase g_DiaRegToRegRelativeArm64 {
36
    { CV_ARM64_PC, rriInstructionPointer },
37
    { CV_ARM64_FP, rriStackFrame },
38
    { CV_ARM64_SP, rriStackPointer },
39
};
40

41
const DiaRegToRegRelativeBase g_DiaRegToRegRelativeArm {
42
    { CV_ARM_PC,    rriInstructionPointer },
43
    { CV_ARM_R11,   rriStackFrame },
44
    { CV_ARM_SP,    rriStackPointer },
45
};
46

47
} // end nameless namespace
48

49
///////////////////////////////////////////////////////////////////////////////
50

51
const std::wstring DiaException::descPrefix(L"pyDia: ");
52

53
std::wstring DiaException::makeFullDesc(const std::wstring &desc, HRESULT hres, IDiaSymbol *symbol /*= NULL*/)
54
{
55
    std::wstringstream sstream;
56
    sstream << descPrefix << desc << L" failed" << std::endl;
57
    if (symbol)
58
    {
59
        BSTR bstrName = NULL;
60
        HRESULT locRes = symbol->get_undecoratedName(&bstrName);
61
        if (S_OK == locRes && bstrName)
62
        {
63
            sstream << L"Symbol name: \"" << _bstr_t(bstrName, false) << L"\"";
64
        }
65
        else
66
        {
67
            locRes = symbol->get_name(&bstrName);
68
            if (S_OK == locRes && bstrName)
69
            {
70
                sstream << L"Symbol name: " << _bstr_t(bstrName, false);
71
            }
72
            else
73
            {
74
                sstream << L"Symbol: ";
75
            }
76
        }
77

78
        DWORD dwValue;
79
        locRes = symbol->get_relativeVirtualAddress(&dwValue);
80
        if (S_OK == locRes)
81
        {
82
            sstream << L", RVA= 0x" << std::hex << dwValue;
83
        }
84

85
        locRes = symbol->get_symTag(&dwValue);
86
        if (S_OK == locRes)
87
        {
88
            sstream << L", tag= " << std::dec << dwValue;
89
        }
90

91
        locRes = symbol->get_locationType(&dwValue);
92
        if (S_OK == locRes)
93
        {
94
            sstream << L", location: " << std::dec << dwValue;
95
        }
96

97
        sstream << std::endl;
98
    }
99
    sstream << L"Return value is 0x" << std::hex << hres;
100

101
    switch (hres)
102
    {
103
#define _CASE_DIA_ERROR(x)  case E_PDB_##x: sstream << L": E_PDB_" L#x << std::endl; break
104

105
    _CASE_DIA_ERROR(USAGE);
106
    _CASE_DIA_ERROR(OUT_OF_MEMORY);
107
    _CASE_DIA_ERROR(FILE_SYSTEM);
108
    _CASE_DIA_ERROR(NOT_FOUND);
109
    _CASE_DIA_ERROR(INVALID_SIG);
110
    _CASE_DIA_ERROR(INVALID_AGE);
111
    _CASE_DIA_ERROR(PRECOMP_REQUIRED);
112
    _CASE_DIA_ERROR(OUT_OF_TI);
113
    _CASE_DIA_ERROR(NOT_IMPLEMENTED);
114
    _CASE_DIA_ERROR(V1_PDB);
115
    _CASE_DIA_ERROR(FORMAT);
116
    _CASE_DIA_ERROR(LIMIT);
117
    _CASE_DIA_ERROR(CORRUPT);
118
    _CASE_DIA_ERROR(TI16);
119
    _CASE_DIA_ERROR(ACCESS_DENIED);
120
    _CASE_DIA_ERROR(ILLEGAL_TYPE_EDIT);
121
    _CASE_DIA_ERROR(INVALID_EXECUTABLE);
122
    _CASE_DIA_ERROR(DBG_NOT_FOUND);
123
    _CASE_DIA_ERROR(NO_DEBUG_INFO);
124
    _CASE_DIA_ERROR(INVALID_EXE_TIMESTAMP);
125
    _CASE_DIA_ERROR(RESERVED);
126
    _CASE_DIA_ERROR(DEBUG_INFO_NOT_IN_PDB);
127
    _CASE_DIA_ERROR(SYMSRV_BAD_CACHE_PATH);
128
    _CASE_DIA_ERROR(SYMSRV_CACHE_FULL);
129

130
#undef _CASE_DIA_ERROR
131
    default:
132
        {
133
            PWCHAR errMessage = NULL;
134
            FormatMessageW(
135
                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
136
                NULL,
137
                hres,
138
                MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
139
                (PWCHAR)&errMessage,
140
                0,
141
                NULL);
142
            if (errMessage)
143
            {
144
                sstream << L": " << std::endl;
145
                sstream << errMessage;
146
                LocalFree(errMessage);
147
            }
148
            else
149
            {
150
                sstream << std::endl;
151
            }
152
        }
153
    }
154

155
    return sstream.str();
156
}
157

158
////////////////////////////////////////////////////////////////////////////////
159

160
#define callSymbol(method) \
161
    callSymbolT( &IDiaSymbol::##method, L#method)
162

163
//////////////////////////////////////////////////////////////////////////////////
164

165
std::wstring getBasicTypeName( ULONG basicType )
166
{
167
    for ( size_t i = 0; i < DiaSymbol::cntBasicTypeName; ++i )
168
    {
169
        if ( basicType == DiaSymbol::basicTypeName[i].first )
170
            return std::wstring( DiaSymbol::basicTypeName[i].second );
171
    }
172

173
    std::wstringstream   sstr;
174

175
    sstr << L"faild to find basic type with index %d" << basicType;
176

177
    throw DiaException( sstr.str() );
178
}
179

180
////////////////////////////////////////////////////////////////////////////////
181

182
DiaSymbol::DiaSymbol(const DiaSymbolPtr &_symbol, const std::wstring &_scope, MachineTypes machineType)
183
    : m_symbol(_symbol), m_scope(_scope), m_machineType(machineType)
184
{
185
}
186

187
//////////////////////////////////////////////////////////////////////////////////
188

189
SymbolPtr DiaSymbol::fromGlobalScope( IDiaSymbol *_symbol, const std::wstring& _scope )
190
{
191
    MachineTypes machineType;
192
    HRESULT hres = _symbol->get_machineType( (DWORD*)&machineType);
193
    if (S_OK != hres)
194
        throw DiaException( L"IDiaSymbol::get_machineType", hres);
195
    if (!machineType)
196
        machineType = machine_I386;
197

198
    return SymbolPtr(new DiaSymbol(DiaSymbolPtr(_symbol), _scope, machineType));
199
}
200

201
//////////////////////////////////////////////////////////////////////////////////
202

203
SymbolPtrList  DiaSymbol::findChildren(
204
        ULONG symTag,
205
        const std::wstring &name,
206
        bool caseSensitive
207
    )
208
{
209
    DiaEnumSymbolsPtr symbols;
210
    HRESULT hres;
211

212
    const std::wstring decoratedMask = name.empty() ? 
213
        std::wstring() : std::wstring(L"*") + name.c_str() + L"*";
214

215
    hres = 
216
        m_symbol->findChildren(
217
            static_cast<enum ::SymTagEnum>(symTag),
218
            decoratedMask.empty() ? NULL : decoratedMask.c_str(),
219
            (caseSensitive ? nsCaseSensitive : nsCaseInsensitive) | nsfUndecoratedName | nsfRegularExpression,
220
            &symbols);
221

222
    if (S_OK != hres)
223
        throw DiaException(L"Call IDiaSymbol::findChildren", hres);
224

225
    SymbolPtrList childList;
226

227
    DiaSymbolPtr child;
228
    ULONG celt;
229
    while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
230
    {
231
        SymbolPtr symbol( new DiaSymbol(child, m_scope, m_machineType) );
232
        child = NULL;
233

234
        if ( name.empty() || 
235
             ::SymMatchStringW(symbol->getName().c_str(), name.c_str(), caseSensitive) )
236
        {
237
            childList.push_back( symbol );
238
        }
239
    }
240

241
    return childList;
242
}
243

244
//////////////////////////////////////////////////////////////////////////////////
245

246
SymbolPtrList DiaSymbol::findChildrenByRVA(unsigned long symTag, unsigned long rva)
247
{
248
    DiaEnumSymbolsPtr symbols;
249
    HRESULT hres;
250

251
    hres = m_symbol->findChildrenExByRVA(
252
        static_cast<enum ::SymTagEnum>(symTag),
253
        NULL,
254
        nsCaseSensitive | nsfUndecoratedName,
255
        rva,
256
        &symbols);
257

258
    if (S_OK != hres)
259
        throw DiaException(L"Call IDiaSymbol::findChildrenExByRVA", hres);
260

261
    SymbolPtrList childList;
262
    DiaSymbolPtr child;
263
    ULONG celt;
264
    while (SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1))
265
    {
266
        SymbolPtr symbol(new DiaSymbol(child, m_scope, m_machineType));
267
        child = NULL;
268

269
        childList.push_back(symbol);
270
    }
271

272
    return childList;
273
}
274

275
//////////////////////////////////////////////////////////////////////////////////
276

277
ULONG DiaSymbol::getBaseType()
278
{
279
    return callSymbol(get_baseType);
280
}
281

282
//////////////////////////////////////////////////////////////////////////////////
283

284
ULONG DiaSymbol::getBitPosition()
285
{
286
    return callSymbol(get_bitPosition);
287
}
288

289
//////////////////////////////////////////////////////////////////////////////////
290

291
size_t DiaSymbol::getChildCount(ULONG symTag)
292
{
293
    DiaEnumSymbolsPtr symbols;
294
    HRESULT hres = 
295
        m_symbol->findChildren(
296
            static_cast<enum ::SymTagEnum>(symTag),
297
            NULL,
298
            nsfCaseSensitive | nsfUndecoratedName,
299
            &symbols);
300
    if (S_OK != hres)
301
        throw DiaException(L"Call IDiaSymbol::findChildren", hres);
302

303
    LONG count;
304
    hres = symbols->get_Count(&count);
305
    if (S_OK != hres)
306
        throw DiaException(L"Call IDiaEnumSymbols::get_Count", hres);
307

308
    return count;
309
}
310

311
////////////////////////////////////////////////////////////////////////////////
312

313
SymbolPtr DiaSymbol::getChildByIndex(ULONG symTag, ULONG _index )
314
{
315
    DiaEnumSymbolsPtr symbols;
316
    HRESULT hres = 
317
        m_symbol->findChildren(
318
            static_cast<enum ::SymTagEnum>(symTag),
319
            NULL,
320
            nsfCaseSensitive | nsfUndecoratedName,
321
            &symbols);
322
    if (S_OK != hres)
323
        throw DiaException(L"Call IDiaSymbol::findChildren", hres);
324

325
    //LONG count;
326
    //hres = symbols->get_Count(&count);
327
    //if (S_OK != hres)
328
    //    throw DiaException("Call IDiaEnumSymbols::get_Count", hres);
329

330
    //if (LONG(_index) >= count)
331
    //{
332
    //    throw PyException( PyExc_IndexError, "Index out of range");
333
    //}
334

335
    DiaSymbolPtr child;
336
    hres = symbols->Item(_index, &child);
337
    if (S_OK != hres)
338
        throw DiaException(L"Call IDiaEnumSymbols::Item", hres);
339

340
    return SymbolPtr( new DiaSymbol(child, m_scope, m_machineType) );
341
}
342

343
////////////////////////////////////////////////////////////////////////////////
344

345

346
SymbolPtr DiaSymbol::getChildByName(const std::wstring &name )
347
{
348
    // ���� ������ ����������
349
    DiaEnumSymbolsPtr symbols;
350
    HRESULT hres = 
351
        m_symbol->findChildren(
352
            ::SymTagNull,
353
            _bstr_t(name.c_str()),
354
            nsfCaseSensitive,
355
            &symbols);
356
    if (S_OK != hres)
357
        throw DiaException(L"Call IDiaSymbol::findChildren", hres);
358

359
    LONG count;
360
    hres = symbols->get_Count(&count);
361
    if (S_OK != hres)
362
        throw DiaException(L"Call IDiaEnumSymbols::get_Count", hres);
363

364
    if (count > 0)
365
    {
366
        DiaSymbolPtr child;
367
        hres = symbols->Item(0, &child);
368
        if (S_OK != hres)
369
            throw DiaException(L"Call IDiaEnumSymbols::Item", hres);
370

371
        return SymbolPtr( new DiaSymbol(child, m_scope, m_machineType) );
372
    }
373

374
    symbols = NULL;
375
    hres = 
376
        m_symbol->findChildren(
377
            ::SymTagNull,
378
            _bstr_t((std::wstring(L"*") + name + L"*").c_str()),
379
            nsfCaseSensitive | nsfRegularExpression | nsfUndecoratedName,
380
            &symbols);
381
    if (S_OK != hres)
382
        throw DiaException(L"Call IDiaSymbol::findChildren", hres);
383

384
    hres = symbols->get_Count(&count);
385
    if (S_OK != hres)
386
        throw DiaException(L"Call IDiaEnumSymbols::get_Count", hres);
387

388
    if (count > 0)
389
    {
390
        DiaSymbolPtr child;
391
        ULONG celt;
392
        while ( SUCCEEDED(symbols->Next(1, &child, &celt)) && (celt == 1) )
393
        {
394
            SymbolPtr symbol ( new DiaSymbol(child, m_scope, m_machineType) );
395
            if (symbol->getName() == name)
396
                return symbol;
397

398
            child = NULL;
399
        }
400
    }
401

402
    throw DiaException(std::wstring(L"symbol \"") + name + L"\" is not found");
403
}
404

405
//////////////////////////////////////////////////////////////////////////////
406

407
size_t DiaSymbol::getCount()
408
{
409
    return callSymbol(get_count);
410
}
411

412
////////////////////////////////////////////////////////////////////////////////
413

414
ULONG DiaSymbol::getDataKind()
415
{
416
    return callSymbol(get_dataKind);
417
}
418

419
////////////////////////////////////////////////////////////////////////////////
420

421
ULONG DiaSymbol::getRegisterId()
422
{
423
    return callSymbol(get_registerId);
424
}
425

426
////////////////////////////////////////////////////////////////////////////////
427

428
unsigned long DiaSymbol::getRegRelativeId()
429
{
430
    switch (m_machineType)
431
    {
432
    case IMAGE_FILE_MACHINE_AMD64:
433
        return getRegRelativeIdImpl(g_DiaRegToRegRelativeAmd64);
434
    case IMAGE_FILE_MACHINE_I386:
435
        return getRegRelativeIdImpl(g_DiaRegToRegRelativeI386);
436
    case IMAGE_FILE_MACHINE_ARM64:
437
        return getRegRelativeIdImpl(g_DiaRegToRegRelativeArm64);
438
    case IMAGE_FILE_MACHINE_ARMNT:
439
        return getRegRelativeIdImpl(g_DiaRegToRegRelativeArm);
440
    }
441
    throw DiaException(L"Unsupported machine type");
442
}
443

444
////////////////////////////////////////////////////////////////////////////////
445

446
SymbolPtr DiaSymbol::getObjectPointerType()
447
{
448
    DiaSymbolPtr diaSymbol(callSymbol(get_objectPointerType));
449
    return SymbolPtr( new DiaSymbol( diaSymbol, m_scope, m_machineType ) );
450
}
451

452
////////////////////////////////////////////////////////////////////////////////
453

454
ULONG DiaSymbol::getCallingConvention()
455
{
456
    return callSymbol(get_callingConvention);
457
}
458

459
////////////////////////////////////////////////////////////////////////////////
460

461
SymbolPtr DiaSymbol::getClassParent()
462
{
463
    DiaSymbolPtr diaSymbol(callSymbol(get_classParent));
464
    return SymbolPtr( new DiaSymbol( diaSymbol, m_scope, m_machineType ) );
465
}
466

467

468
////////////////////////////////////////////////////////////////////////////////
469

470
ULONG DiaSymbol::getRegRelativeIdImpl(const DiaRegToRegRelativeBase &DiaRegToRegRelative)
471
{
472
    const DWORD registerId = callSymbol(get_registerId);
473
    DiaRegToRegRelativeBase::const_iterator it = DiaRegToRegRelative.find(registerId);
474
    if (it == DiaRegToRegRelative.end())
475
        throw DiaException(L"Cannot convert DIA register ID to relative register ID");
476
    return it->second;
477
}
478

479
////////////////////////////////////////////////////////////////////////////////
480

481
bool DiaSymbol::isUndecorated(const std::wstring &undecName)
482
{
483
    if (m_machineType != machine_I386)
484
        return true;
485

486
    BSTR bstrName = NULL;
487
    HRESULT hres = m_symbol->get_name(&bstrName);
488
    if (S_OK != hres)
489
        return true;
490

491
    return !( undecName == std::wstring( _bstr_t(bstrName, false) ) );
492
}
493

494
////////////////////////////////////////////////////////////////////////////////
495

496
SymbolPtr DiaSymbol::getIndexType()
497
{
498
    DiaSymbolPtr diaSymbol(callSymbol(get_arrayIndexType));
499
    return SymbolPtr( new DiaSymbol(diaSymbol, m_scope, m_machineType) );
500
}
501

502
////////////////////////////////////////////////////////////////////////////////
503

504
ULONG DiaSymbol::getLocType()
505
{
506
    return callSymbol(get_locationType);
507
}
508

509
//////////////////////////////////////////////////////////////////////////////
510

511
static const  boost::wregex  stdcallMatch(L"^_(\\w+)(@\\d+)?$");
512
static const  boost::wregex  fastcallMatch(L"^@(\\w+)(@\\d+)?$");
513

514
std::wstring DiaSymbol::getName()
515
{
516
    HRESULT hres;
517
    BSTR bstrName = NULL;
518

519
    ULONG symTag;
520
    hres = m_symbol->get_symTag( &symTag );
521

522
    if ( FAILED( hres ) )
523
        throw DiaException(L"Call IDiaSymbol::get_symTag", hres);
524

525
    if (symTag == SymTagData || symTag == SymTagFunction)
526
    {
527
        hres = m_symbol->get_name(&bstrName);
528
        if (S_OK == hres)
529
            return std::wstring( _bstr_t(bstrName, false) );
530
    }
531

532
    if( symTag == SymTagData || symTag == SymTagFunction || symTag == SymTagPublicSymbol )
533
    {
534
        hres = m_symbol->get_undecoratedNameEx( UNDNAME_NAME_ONLY, &bstrName);
535
        if ( FAILED( hres ) )
536
            throw DiaException(L"Call IDiaSymbol::get_undecoratedNameEx", hres);
537

538
        if ( bstrName )
539
        {
540
            std::wstring retStr = _bstr_t(bstrName, false);
541

542
            if ( (symTag == SymTagPublicSymbol) && !isUndecorated(retStr) )
543
            {
544
                boost::wsmatch  matchResult;
545

546
                if ( boost::regex_match( retStr, matchResult, stdcallMatch ) )
547
                    return std::wstring( matchResult[1].first, matchResult[1].second );
548

549
                if ( boost::regex_match( retStr, matchResult, fastcallMatch ) )
550
                    return std::wstring( matchResult[1].first, matchResult[1].second );
551
            }
552

553
            return retStr; 
554
        }
555
    }
556

557
    bstrName = callSymbol(get_name);
558

559
    return std::wstring( _bstr_t(bstrName, false) );
560
}
561

562
std::wstring DiaSymbol::getScopeName()
563
{
564
  return m_scope;
565
}
566

567
///////////////////////////////////////////////////////////////////////////////
568

569
LONG DiaSymbol::getOffset()
570
{
571
    return callSymbol(get_offset);
572
}
573

574
////////////////////////////////////////////////////////////////////////////////
575

576
ULONG DiaSymbol::getRva()
577
{
578
    return callSymbol(get_relativeVirtualAddress);
579
}
580

581
////////////////////////////////////////////////////////////////////////////////
582

583
size_t DiaSymbol::getSize()
584
{
585
    return static_cast<size_t>( callSymbol(get_length) );
586
}
587

588
////////////////////////////////////////////////////////////////////////////////
589

590
SymTags DiaSymbol::getSymTag()
591
{
592
    return static_cast<SymTags>( callSymbol(get_symTag) );
593
}
594

595
////////////////////////////////////////////////////////////////////////////////
596

597
SymbolPtr DiaSymbol::getType()
598
{
599
    DiaSymbolPtr diaSymbol(callSymbol(get_type));
600
    return SymbolPtr( new DiaSymbol( diaSymbol, m_scope, m_machineType ) );
601
}
602

603
////////////////////////////////////////////////////////////////////////////////
604

605
ULONG DiaSymbol::getUdtKind()
606
{
607
    return callSymbol(get_udtKind);
608
}
609

610
////////////////////////////////////////////////////////////////////////////////
611

612
ULONGLONG DiaSymbol::getVa()
613
{
614
    return callSymbol(get_virtualAddress);
615
}
616

617
////////////////////////////////////////////////////////////////////////////////
618

619
void DiaSymbol::getValue( NumVariant &btv )
620
{
621
    CComVariant  vtValue;
622
    HRESULT hres = m_symbol->get_value(&vtValue);
623
    if (S_OK != hres)
624
        throw DiaException( L"Call IDiaSymbol::get_value", hres);
625

626
    switch (vtValue.vt)
627
    {
628
    case VT_I1:
629
        btv = NumVariant(vtValue.cVal);
630
        break;
631

632
    case VT_UI1:
633
        btv = NumVariant(vtValue.bVal);
634
        break;
635

636
    case VT_BOOL:
637
        btv = NumVariant(vtValue.boolVal);
638
        break;
639

640
    case VT_I2:
641
        btv = NumVariant(vtValue.iVal);
642
        break;
643

644
    case VT_UI2:
645
        btv = NumVariant(vtValue.uiVal);
646
        break;
647

648
    case VT_I4:
649
    case VT_INT:
650
        btv = NumVariant(vtValue.lVal);
651
        break;
652

653
    case VT_UI4:
654
    case VT_UINT:
655
    case VT_ERROR:
656
    case VT_HRESULT:
657
        btv = NumVariant(vtValue.ulVal);
658
        break;
659

660
    case VT_I8:
661
        btv = NumVariant(vtValue.llVal);
662
        break;
663

664
    case VT_UI8:
665
        btv = NumVariant(vtValue.llVal);
666
        break;
667

668
    case VT_R4:
669
        btv = NumVariant(vtValue.fltVal);
670
        break;
671

672
    case VT_R8:
673
        btv = NumVariant(vtValue.dblVal);
674
        break;
675

676
    default:
677
        throw DbgException( "Unsupported const value" );
678
    }
679
}
680

681
//////////////////////////////////////////////////////////////////////////////
682

683
int DiaSymbol::getVirtualBasePointerOffset()
684
{
685
    return callSymbol(get_virtualBasePointerOffset);
686
}
687

688
////////////////////////////////////////////////////////////////////////////////
689

690
ULONG DiaSymbol::getVirtualBaseDispIndex()
691
{
692
    return callSymbol(get_virtualBaseDispIndex);
693
}
694

695
////////////////////////////////////////////////////////////////////////////////
696

697
ULONG DiaSymbol::getVirtualBaseDispSize()
698
{
699
    DiaSymbolPtr diaSymbol(callSymbol(get_virtualBaseTableType));
700
    SymbolPtr baseTableType = SymbolPtr( new DiaSymbol( diaSymbol, m_scope, m_machineType ) );
701

702
    return (ULONG)baseTableType->getType()->getSize();
703
}
704

705
//////////////////////////////////////////////////////////////////////////////
706

707
bool DiaSymbol::isBasicType()
708
{
709
    DWORD baseType = btNoType;
710
    return 
711
        SUCCEEDED( m_symbol->get_baseType(&baseType) ) && 
712
        (btNoType != baseType);
713
}
714

715
//////////////////////////////////////////////////////////////////////////////
716

717
bool DiaSymbol::isConstant()
718
{
719
    HRESULT  hres;
720
    BOOL  retBool = FALSE;
721

722
    hres = m_symbol->get_constType( &retBool );
723
    if ( FAILED( hres ) )
724
        throw DiaException(L"Call IDiaSymbol::get_constType", hres, m_symbol);
725

726
    return !!retBool;
727
}
728

729
//////////////////////////////////////////////////////////////////////////////
730

731
bool DiaSymbol::isIndirectVirtualBaseClass()
732
{
733
    return !!callSymbol(get_indirectVirtualBaseClass);
734
}
735

736
//////////////////////////////////////////////////////////////////////////////
737

738
bool DiaSymbol::isVirtualBaseClass()
739
{
740
    return !!callSymbol(get_virtualBaseClass);
741
}
742

743
//////////////////////////////////////////////////////////////////////////////
744

745
bool DiaSymbol::isVirtual()
746
{
747
    return !!callSymbol(get_virtual);
748
}
749

750
///////////////////////////////////////////////////////////////////////////////
751

752
SymbolPtr DiaSymbol::getVirtualTableShape()
753
{
754
    DiaSymbolPtr diaSymbol(callSymbol(get_virtualTableShape));
755
    return SymbolPtr( new DiaSymbol( diaSymbol, m_scope, m_machineType ) );
756
}
757

758
//////////////////////////////////////////////////////////////////////////////
759

760
unsigned long DiaSymbol::getVirtualBaseOffset()
761
{
762
    return callSymbol(get_virtualBaseOffset);
763
}
764

765
//////////////////////////////////////////////////////////////////////////////
766

767
SymbolPtrList DiaSymbol::findInlineFramesByVA(MEMOFFSET_64 va)
768
{
769
    CComPtr<IDiaEnumSymbols>  symEnum;
770
    HRESULT hres = m_symbol->findInlineFramesByVA(va, &symEnum);
771
    if (FAILED(hres))
772
        return SymbolPtrList();
773

774
    LONG  count;
775
    hres = symEnum->get_Count(&count);
776
    if (S_OK != hres)
777
        throw DiaException(L"Call IDiaSymbol::findInlineFramesByVA", hres);
778

779
    SymbolPtrList  symList;
780

781
    for (auto i = 0; i < count; ++i)
782
    {
783
        CComPtr<IDiaSymbol> sym;
784
        hres = symEnum->Item(i, &sym);
785
        if (FAILED(hres) )
786
            throw DiaException(L"Call IDiaEnumSymbols::Item", hres);     
787

788
        SymbolPtr symbol(new DiaSymbol(sym, m_scope, m_machineType));
789

790
        symList.push_back(symbol);
791
    }
792

793
    return symList;
794
}
795

796
//////////////////////////////////////////////////////////////////////////////
797

798
void DiaSymbol::getInlineSourceLine(MEMOFFSET_64 offset, std::wstring &fileName, unsigned long &lineNo)
799
{
800
    CComPtr<IDiaEnumLineNumbers>  enumLineNumbers;
801

802
    HRESULT  hres = m_symbol->findInlineeLinesByVA(offset, 1, &enumLineNumbers);
803
    if (FAILED(hres) )
804
        throw DiaException(L"Call IDiaSymbol::findInlineeLinesByVA", hres);
805

806
    DiaLineNumberPtr  sourceLine;
807
    hres = enumLineNumbers->Item(0, &sourceLine);
808
    if (S_OK != hres)
809
        throw DiaException(L"failed to find source line");
810

811
    DiaSourceFilePtr  sourceFile;
812
    hres = sourceLine->get_sourceFile(&sourceFile);
813
    if (S_OK != hres)
814
        throw DiaException(L"failed to find source line");
815

816
    autoBstr  fileNameBstr;
817
    hres = sourceFile->get_fileName(&fileNameBstr);
818
    if (S_OK != hres)
819
        throw DiaException(L"failed to find source line");
820
    fileName = _bstr_t(fileNameBstr, false);
821

822
    hres = sourceLine->get_lineNumber(&lineNo);
823
    if (S_OK != hres)
824
        throw DiaException(L"failed to find source line");
825
}
826

827
//////////////////////////////////////////////////////////////////////////////
828

829
SymbolPtr DiaSymbol::getLexicalParent()
830
{
831
    DiaSymbolPtr diaSymbol(callSymbol(get_lexicalParent));
832
    return SymbolPtr(new DiaSymbol(diaSymbol, m_scope, m_machineType));
833
}
834

835
//////////////////////////////////////////////////////////////////////////////
836

837
std::wstring DiaSession::getScopeName( IDiaSession* session, IDiaSymbol *globalScope )
838
{
839
  std::wstring scopeName;
840
  // Try to get module name as scope
841
  try
842
  {
843
    ULONGLONG loadBase;
844
    HRESULT hres = session->get_loadAddress(&loadBase);
845
    if (S_OK != hres)
846
      return L"";
847

848
    scopeName = getModuleName(loadBase);
849
  }
850
  catch (DbgException e) // fallback to pdb name
851
  {
852
    HRESULT hres;
853
    BSTR bstrName = NULL;
854
    hres = globalScope->get_name(&bstrName);
855
    if (S_OK == hres)
856
      scopeName = std::wstring(_bstr_t(bstrName, false));
857
  }
858
  return scopeName;
859
}
860

861
//////////////////////////////////////////////////////////////////////////////
862

863
SymbolPtr DiaSession::findByRva( ULONG rva, ULONG symTag, LONG* pdisplacement )
864
{
865
    DiaSymbolPtr child;
866
    LONG displacement;
867

868
    HRESULT hres = 
869
        m_session->findSymbolByRVAEx(
870
            rva,
871
            static_cast<enum ::SymTagEnum>(symTag),
872
            &child,
873
            &displacement);
874

875
    if (S_OK != hres)
876
        throw DiaException(L"Call IDiaSession::findSymbolByRVAEx", hres);
877
    if (!child)
878
        throw DiaException(L"Call IDiaSession::findSymbolByRVAEx", E_UNEXPECTED);
879
    if ( !pdisplacement && displacement)
880
        throw DiaException(L"Call IDiaSession::findSymbolByRVAEx failed to find symbol" );
881

882
    if (pdisplacement)
883
        *pdisplacement = displacement;
884

885
    return SymbolPtr( new DiaSymbol(child, m_globalSymbol->getScopeName(), m_globalSymbol->getMachineType() ) );
886
}
887

888
///////////////////////////////////////////////////////////////////////////////
889

890
void DiaSession::getSourceLine( ULONG64 offset, std::wstring &fileName, ULONG &lineNo, LONG &displacement )
891
{
892
    DiaEnumLineNumbersPtr  lines;
893

894
    HRESULT hres = m_session->findLinesByVA( offset, 1, &lines );
895
    if (S_OK != hres)
896
        throw DiaException(L"failed to find source line");
897

898
    DiaLineNumberPtr  sourceLine;
899
    hres = lines->Item( 0, &sourceLine );
900
    if (S_OK != hres)
901
        throw DiaException(L"failed to find source line");
902

903
    DiaSourceFilePtr  sourceFile;
904
    hres = sourceLine->get_sourceFile( &sourceFile );
905
    if (S_OK != hres)
906
        throw DiaException(L"failed to find source line");
907
    
908
    autoBstr  fileNameBstr;
909
    hres = sourceFile->get_fileName ( &fileNameBstr );
910
    if (S_OK != hres)
911
        throw DiaException(L"failed to find source line");
912
    fileName = _bstr_t(fileNameBstr, false);
913

914
    hres = sourceLine->get_lineNumber( &lineNo);
915
    if (S_OK != hres)
916
        throw DiaException(L"failed to find source line");
917

918
    ULONGLONG  va;
919
    hres = sourceLine->get_virtualAddress ( &va );
920
    if (S_OK != hres)
921
        throw DiaException(L"failed to find source line");
922

923
    displacement = (LONG)( (LONGLONG)offset - (LONGLONG)va );
924
}
925

926

927
///////////////////////////////////////////////////////////////////////////////
928

929
}; // kdlib nemaspace end
930

931

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.